<commit_before>/*
 * (C) Copyright 2014 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 */

#include <gst/gst.h>
#include "Processor.hpp"
#include "WebSocketTransport.hpp"
#include "WebSocketEventHandler.hpp"
#include <jsonrpc/JsonRpcUtils.hpp>
#include <jsonrpc/JsonRpcConstants.hpp>
#include <KurentoException.hpp>

#include <boost/filesystem.hpp>

#include <type_traits>

#define GST_CAT_DEFAULT kurento_websocket_transport
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoWebSocketTransport"

typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;

namespace kurento
{

const std::string SESSION_ID = "sessionId";

/* Default config values */
const ushort WEBSOCKET_PORT_DEFAULT = 8888;
const std::string WEBSOCKET_PATH_DEFAULT = "kurento";
const int WEBSOCKET_THREADS_DEFAULT = 10;

const std::chrono::seconds KEEP_ALIVE_PERIOD (60);

class configuration_exception : public std::exception
{
public:
  configuration_exception (std::string message) {
    this->message = message;
  }

  virtual const char *what() const _GLIBCXX_USE_NOEXCEPT {
    return message.c_str();
  }

private:
  std::string message;
};

WebSocketTransport::WebSocketTransport (const boost::property_tree::ptree
                                        &config,
                                        std::shared_ptr<Processor> processor) : processor (processor)
{
  ushort port;
  ushort securePort;

  port = config.get<ushort> ("mediaServer.net.websocket.port",
                             WEBSOCKET_PORT_DEFAULT);
  securePort = config.get<ushort> ("mediaServer.net.websocket.secure.port", 0);

  path = config.get<std::string> ("mediaServer.net.websocket.path",
                                  WEBSOCKET_PATH_DEFAULT);

  try {
    n_threads = config.get<uint> ("mediaServer.net.websocket.threads");

    if (n_threads < 1) {
      throw boost::property_tree::ptree_bad_data ("Invalid threads number",
          n_threads);
    }
  } catch (const boost::property_tree::ptree_error &err) {
    GST_WARNING ("Setting default listener threads %d to websocket",
                 WEBSOCKET_THREADS_DEFAULT);
    n_threads = WEBSOCKET_THREADS_DEFAULT;
  }

  processor->setEventSubscriptionHandler (std::bind (
      &WebSocketTransport::processSubscription, this, std::placeholders::_1,
      std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) );

  /* Configure server */
  server.clear_access_channels (websocketpp::log::alevel::all);
  server.clear_error_channels (websocketpp::log::alevel::all);

  server.init_asio (&ios);
  server.set_reuse_addr (true);
  server.set_open_handler (std::bind ( (void (WebSocketTransport::*) (
                                          WebSocketServer *, websocketpp::connection_hdl) )
                                       &WebSocketTransport::openHandler, this,
                                       &server, std::placeholders::_1) );
  server.set_close_handler (std::bind (&WebSocketTransport::closeHandler, this,
                                       std::placeholders::_1) );
  server.set_message_handler (std::bind ( (void (WebSocketTransport::*) (
      WebSocketServer *, websocketpp::connection_hdl,
      WebSocketServer::message_ptr) ) &WebSocketTransport::processMessage,
                                          this, &server, std::placeholders::_1,
                                          std::placeholders::_2) );

  try {
    server.listen (port);
  } catch (std::error_code &e) {
    GST_ERROR ("Error starting listen for weboscket transport on port %d", port);
    exit (1);
  }

  /* Configure secure server if enabled */
  if (securePort != 0) {
    try {
      std::string password;
      boost::filesystem::path certificateFile;

      try {
        password =
          config.get<std::string> ("mediaServer.net.websocket.secure.password");
      } catch (const boost::property_tree::ptree_error &err) {
        throw configuration_exception ("Cannot get password for secure websocket");
      }

      try {
        certificateFile = boost::filesystem::path (
                            config.get<std::string> ("mediaServer.net.websocket.secure.certificate") );

        if (certificateFile.is_relative() ) {
          certificateFile = boost::filesystem::path (
                              config.get<std::string> ("configPath") ) / certificateFile;
        }

        if (!boost::filesystem::exists (certificateFile) ) {
          throw configuration_exception ("Cannot get cerfificate file for secure websocket, configured file "<commit_msg>WebSocketTransport: Fix typo in error trace<commit_after>/*
 * (C) Copyright 2014 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 */

#include <gst/gst.h>
#include "Processor.hpp"
#include "WebSocketTransport.hpp"
#include "WebSocketEventHandler.hpp"
#include <jsonrpc/JsonRpcUtils.hpp>
#include <jsonrpc/JsonRpcConstants.hpp>
#include <KurentoException.hpp>

#include <boost/filesystem.hpp>

#include <type_traits>

#define GST_CAT_DEFAULT kurento_websocket_transport
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define GST_DEFAULT_NAME "KurentoWebSocketTransport"

typedef websocketpp::lib::shared_ptr<boost::asio::ssl::context> context_ptr;

namespace kurento
{

const std::string SESSION_ID = "sessionId";

/* Default config values */
const ushort WEBSOCKET_PORT_DEFAULT = 8888;
const std::string WEBSOCKET_PATH_DEFAULT = "kurento";
const int WEBSOCKET_THREADS_DEFAULT = 10;

const std::chrono::seconds KEEP_ALIVE_PERIOD (60);

class configuration_exception : public std::exception
{
public:
  configuration_exception (std::string message) {
    this->message = message;
  }

  virtual const char *what() const _GLIBCXX_USE_NOEXCEPT {
    return message.c_str();
  }

private:
  std::string message;
};

WebSocketTransport::WebSocketTransport (const boost::property_tree::ptree
                                        &config,
                                        std::shared_ptr<Processor> processor) : processor (processor)
{
  ushort port;
  ushort securePort;

  port = config.get<ushort> ("mediaServer.net.websocket.port",
                             WEBSOCKET_PORT_DEFAULT);
  securePort = config.get<ushort> ("mediaServer.net.websocket.secure.port", 0);

  path = config.get<std::string> ("mediaServer.net.websocket.path",
                                  WEBSOCKET_PATH_DEFAULT);

  try {
    n_threads = config.get<uint> ("mediaServer.net.websocket.threads");

    if (n_threads < 1) {
      throw boost::property_tree::ptree_bad_data ("Invalid threads number",
          n_threads);
    }
  } catch (const boost::property_tree::ptree_error &err) {
    GST_WARNING ("Setting default listener threads %d to websocket",
                 WEBSOCKET_THREADS_DEFAULT);
    n_threads = WEBSOCKET_THREADS_DEFAULT;
  }

  processor->setEventSubscriptionHandler (std::bind (
      &WebSocketTransport::processSubscription, this, std::placeholders::_1,
      std::placeholders::_2, std::placeholders::_3, std::placeholders::_4) );

  /* Configure server */
  server.clear_access_channels (websocketpp::log::alevel::all);
  server.clear_error_channels (websocketpp::log::alevel::all);

  server.init_asio (&ios);
  server.set_reuse_addr (true);
  server.set_open_handler (std::bind ( (void (WebSocketTransport::*) (
                                          WebSocketServer *, websocketpp::connection_hdl) )
                                       &WebSocketTransport::openHandler, this,
                                       &server, std::placeholders::_1) );
  server.set_close_handler (std::bind (&WebSocketTransport::closeHandler, this,
                                       std::placeholders::_1) );
  server.set_message_handler (std::bind ( (void (WebSocketTransport::*) (
      WebSocketServer *, websocketpp::connection_hdl,
      WebSocketServer::message_ptr) ) &WebSocketTransport::processMessage,
                                          this, &server, std::placeholders::_1,
                                          std::placeholders::_2) );

  try {
    server.listen (port);
  } catch (std::error_code &e) {
    GST_ERROR ("Error starting listen for websocket transport on port %d", port);
    exit (1);
  }

  /* Configure secure server if enabled */
  if (securePort != 0) {
    try {
      std::string password;
      boost::filesystem::path certificateFile;

      try {
        password =
          config.get<std::string> ("mediaServer.net.websocket.secure.password");
      } catch (const boost::property_tree::ptree_error &err) {
        throw configuration_exception ("Cannot get password for secure websocket");
      }

      try {
        certificateFile = boost::filesystem::path (
                            config.get<std::string> ("mediaServer.net.websocket.secure.certificate") );

        if (certificateFile.is_relative() ) {
          certificateFile = boost::filesystem::path (
                              config.get<std::string> ("configPath") ) / certificateFile;
        }

        if (!boost::filesystem::exists (certificateFile) ) {
          throw configuration_exception ("Cannot get cerfificate file for secure websocket, configured file "
{'fraction_non_alphanumeric': 0.11020608439646712, 'fraction_numerical': 0.00549558390578999, 'mean_word_length': 3.1026570048309177, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '408683', 'n_tokens_mistral': 2933, 'n_tokens_neox': 2849, 'n_words': 659}