diff --git a/README b/README index 109882e3aa580fd357acbf85f6293352cc90902b..f67caf7c66983d9633b49a71a581ad679044179f 100644 --- a/README +++ b/README @@ -47,7 +47,7 @@ Short description of content of source tree - src/ is the core of DRing. - bin/ contains applications main code. - bin/dbus, the D-Bus XML interfaces, and C++ bindings -- bin/restcpp, the C++ REST API implemented with Restbed +- bin/restcpp, the C++ REST API implemented with Restinio About Savoir-faire Linux ------------------------ @@ -147,7 +147,6 @@ mkdir native cd native ../bootstrap make -make .restbed 2) Then compile the daemon cd ../../ diff --git a/bin/Makefile.am b/bin/Makefile.am index db05bc435d04b610ecd1f3886d9ae3a56cf9496e..7ba24001846c46e6001aae50d0f939c68f08e847 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -37,19 +37,3 @@ endif if RING_NODEJS SUBDIRS+=nodejs endif - -if RING_RESTCPP -SUBDIRS+=restcpp - -sbin_PROGRAMS = restdring - -restdring_SOURCES = main.cpp - -restdring_CXXFLAGS= -g \ - -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/dring \ - -DREST_API \ - -DTOP_BUILDDIR=\"$$(cd "$(top_builddir)"; pwd)\" - -restdring_LDADD = restcpp/libclient_rest.la $(top_builddir)/src/libring.la -endif diff --git a/bin/restcpp/Makefile.am b/bin/restcpp/Makefile.am deleted file mode 100644 index 57401c1fa1fa1e450b8fcf67fe0b10e39580c1f7..0000000000000000000000000000000000000000 --- a/bin/restcpp/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -include $(top_srcdir)/globals.mk - -noinst_LTLIBRARIES = libclient_rest.la - -libclient_rest_la_SOURCES = \ - restclient.cpp \ - restclient.h \ - restconfigurationmanager.cpp \ - restconfigurationmanager.h \ - restvideomanager.cpp \ - restvideomanager.h - -libclient_rest_la_CXXFLAGS = \ - -std=c++14 \ - -g \ - -Wall \ - -Wextra \ - -Wno-reorder \ - -Wno-unused-variable \ - -Wno-unused-parameter \ - -pedantic \ - -I$(top_srcdir)/src - -libclient_rest_la_LDFLAGS = \ - -lpthread \ - -lrestbed diff --git a/bin/restcpp/restclient.cpp b/bin/restcpp/restclient.cpp deleted file mode 100644 index 5e60ff84fa4019cd7c8ca895cba107e2331eedd5..0000000000000000000000000000000000000000 --- a/bin/restcpp/restclient.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2016-2019 Savoir-faire Linux Inc. - * - * Author: Simon Zeni <simon.zeni@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include "restclient.h" - -RestClient::RestClient(int port, int flags, bool persistent) : - service_() -{ - configurationManager_.reset(new RestConfigurationManager()); - videoManager_.reset(new RestVideoManager()); - - if (initLib(flags) < 0) - throw std::runtime_error {"cannot initialize libring"}; - - // Fill the resources - initResources(); - - // Initiate the rest service - settings_ = std::make_shared<restbed::Settings>(); - settings_->set_port(port); - settings_->set_default_header( "Connection", "close" ); - JAMI_INFO("Restclient running on port [%d]", port); - - // Make it run in a thread, because this is a blocking function - restbed = std::thread([this](){ - service_.start(settings_); - }); -} - -RestClient::~RestClient() -{ - JAMI_INFO("destroying RestClient"); - exit(); -} - -int -RestClient::event_loop() noexcept -{ - // While the client is running, the events are polled every 10 milliseconds - JAMI_INFO("Restclient starting to poll events"); - while(!pollNoMore_) - { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - return 0; -} - -int -RestClient::exit() noexcept -{ - try { - // On exit, the client stop polling events - pollNoMore_ = true; - // The rest service is stopped - service_.stop(); - // And the thread running the service is joined - restbed.join(); - endLib(); - } catch (const std::exception& err) { - std::cerr << "quitting: " << err.what() << std::endl; - return 1; - } - - return 0; -} - -int -RestClient::initLib(int flags) -{ - using namespace std::placeholders; - - using std::bind; - using DRing::exportable_callback; - using DRing::CallSignal; - using DRing::ConfigurationSignal; - using DRing::PresenceSignal; - using DRing::AudioSignal; - - using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>; - - auto confM = configurationManager_.get(); - -#ifdef ENABLE_VIDEO - using DRing::VideoSignal; -#endif - - // Configuration event handlers - auto registeredNameFoundCb = exportable_callback<ConfigurationSignal::RegisteredNameFound>([&] - (const std::string& account_id, int state, const std::string& address, const std::string& name){ - auto remainingSessions = configurationManager_->getPendingNameResolutions(name); - - for(auto session: remainingSessions){ - const auto request = session->get_request(); - std::string body = address; - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - if(address.size() > 0) - session->close(restbed::OK, body, headers); - else - session->close(404); - } - }); - - - // This is a short example of a callback using a lambda. In this case, this displays the incoming messages - const std::map<std::string, SharedCallback> configEvHandlers = { - exportable_callback<ConfigurationSignal::IncomingAccountMessage>([] - (const std::string& accountID, const std::string& from, const std::map<std::string, std::string>& payloads){ - JAMI_INFO("accountID : %s", accountID.c_str()); - JAMI_INFO("from : %s", from.c_str()); - JAMI_INFO("payloads"); - for(auto& it : payloads) - JAMI_INFO("%s : %s", it.first.c_str(), it.second.c_str()); - - }), - registeredNameFoundCb, - }; - - if (!DRing::init(static_cast<DRing::InitFlag>(flags))) - return -1; - - registerSignalHandlers(configEvHandlers); - - // Dummy callbacks are registered for the other managers - registerSignalHandlers(std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>()); - registerSignalHandlers(std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>()); -#ifdef ENABLE_VIDEO - registerSignalHandlers(std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>()); -#endif - - if (!DRing::start()) - return -1; - - return 0; -} - -void -RestClient::endLib() noexcept -{ - DRing::fini(); -} - -void -RestClient::initResources() -{ - // This is the function that initiates the resources. - // Each resources is defined by a route and a void function with a shared pointer to the session as argument - - // In this case, here's an example of the default route. It will list all the managers available - auto default_res = std::make_shared<restbed::Resource>(); - default_res->set_path("/"); - default_res->set_method_handler("GET", [](const std::shared_ptr<restbed::Session> session){ - - JAMI_INFO("[%s] GET /", session->get_origin().c_str()); - - std::string body = "Available routes are : \r\n/configurationManager\r\n/videoManager\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - }); - - // And finally, we give the resource to the service to handle it - service_.publish(default_res); - - // For the sake of convenience, each manager sends a vector of their resources - for(auto& it : configurationManager_->getResources()) - service_.publish(it); - - for(auto& it : videoManager_->getResources()) - service_.publish(it); -} diff --git a/bin/restcpp/restclient.h b/bin/restcpp/restclient.h deleted file mode 100644 index cc41213251064f2ac441f43ca72af5925d575f3e..0000000000000000000000000000000000000000 --- a/bin/restcpp/restclient.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2016-2019 Savoir-faire Linux Inc. - * - * Author: Simon Zeni <simon.zeni@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#pragma once - -#include <memory> -#include <chrono> -#include <map> -#include <vector> -#include <string> -#include <iostream> -#include <thread> - -#include <functional> -#include <iterator> -#include <restbed> - -#include "dring/dring.h" -#include "dring/callmanager_interface.h" -#include "dring/configurationmanager_interface.h" -#include "dring/presencemanager_interface.h" -#ifdef ENABLE_VIDEO -#include "dring/videomanager_interface.h" -#endif -#include "logger.h" -#include "restconfigurationmanager.h" -#include "restvideomanager.h" - -class RestClient { - public: - RestClient(int port, int flags, bool persistent); - ~RestClient(); - - int event_loop() noexcept; - int exit() noexcept; - - private: - int initLib(int flags); - void endLib() noexcept; - void initResources(); - - bool pollNoMore_ = false; - - std::unique_ptr<RestConfigurationManager> configurationManager_; - std::unique_ptr<RestVideoManager> videoManager_; - - // Restbed attributes - restbed::Service service_; - std::shared_ptr<restbed::Settings> settings_; - std::thread restbed; -}; diff --git a/bin/restcpp/restconfigurationmanager.cpp b/bin/restcpp/restconfigurationmanager.cpp deleted file mode 100644 index 80a5ce4375a4307a8ea03a30e1b4e4910c000481..0000000000000000000000000000000000000000 --- a/bin/restcpp/restconfigurationmanager.cpp +++ /dev/null @@ -1,1891 +0,0 @@ -/* - * Copyright (C) 2016-2019 Savoir-faire Linux Inc. - * - * Author: Simon Zeni <simon.zeni@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include "restconfigurationmanager.h" - -RestConfigurationManager::RestConfigurationManager() : - resources_() -{ - // We start by filling the resources_ array with all the resources - populateResources(); -} - -std::vector<std::shared_ptr<restbed::Resource>> -RestConfigurationManager::getResources() -{ - return resources_; -} - -// Private - -std::map<std::string, std::string> -RestConfigurationManager::parsePost(const std::string& post) -{ - // Simple function to parse a POST request like "param1=value1¶m2=value2" - std::map<std::string, std::string> data; - - auto split = [](const std::string& s, char delim){ - std::vector<std::string> v; - auto i = 0; - auto pos = s.find(delim); - while (pos != std::string::npos) - { - v.push_back(s.substr(i, pos-i)); - i = ++pos; - pos = s.find(delim, pos); - - if (pos == std::string::npos) - v.push_back(s.substr(i, s.length())); - } - - return v; - }; - - if(post.find_first_of('&') != std::string::npos) - { - std::vector<std::string> v = split(post, '&'); - - for(auto& it : v) - { - std::vector<std::string> tmp = split(it, '='); - data[tmp.front()] = tmp.back(); - } - } - else - { - std::vector<std::string> tmp = split(post, '='); - data[tmp.front()] = tmp.back(); - } - - return data; -} - -void -RestConfigurationManager::populateResources() -{ - // This function is atrociously long and redundant, but it works. Sorry - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/configurationManager"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::defaultRoute, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/accountDetails/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAccountDetails, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/volatileAccountDetails/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getVolatileAccountDetails, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAccountDetails/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::setAccountDetails, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/registerName/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::registerName, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/lookupName/{name: [a-z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::lookupName, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAccountActive/{accountID: [a-z0-9]*}/{status: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setAccountActive, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/accountTemplate/{type: [a-zA-Z]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAccountTemplate, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/addAccount"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::addAccount, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/removeAccount/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::removeAccount, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/accountList"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAccountList, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/sendRegister/{accountID: [a-z0-9]*}/{status: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::sendRegister, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/registerAllAccounts"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::registerAllAccounts, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/sendTextMessage/{accountID: [a-z0-9]*}/{to: [a-z0-9]*}"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::sendTextMessage, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/messageStatus/{id: [0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getMessageStatus, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/tlsDefaultSettings"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getTlsDefaultSettings, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/codecList"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getCodecList, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/supportedTlsMethod"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getSupportedTlsMethod, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/supportedCiphers/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getSupportedCiphers, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/codecDetails/{accountID: [a-z0-9]*}/{codecID: [0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getCodecDetails, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setCodecDetails/{accountID: [a-z0-9]*}/{codecID: [0-9]*}"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::getCodecDetails, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/activeCodecList/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getActiveCodecList, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/audioPluginList"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAudioPluginList, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAudioPlugin/{plugin: [a-zA-Z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setAudioPlugin, this, std::placeholders::_1)); - /// - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/audioOutputDeviceList"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAudioOutputDeviceList, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAudioOutputDevice/{index: [0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setAudioOutputDevice, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAudioInputDevice/{index: [0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setAudioInputDevice, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAudioRingtoneDevice/{plugin: [0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setAudioRingtoneDevice, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/audioInputDeviceList"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAudioInputDeviceList, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/currentAudioDeviceIndex"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getCurrentAudioDevicesIndex, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/audioInputDeviceIndex/{name: [a-zA-Z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAudioInputDeviceIndex, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/audioOutputDeviceIndex/{name: [a-zA-Z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAudioInputDeviceIndex, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/currentAudioOutputPlugin"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getCurrentAudioOutputPlugin, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/noiseSuppressState"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getNoiseSuppressState, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setNoiseSuppressState/{state: (true|false)"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setNoiseSuppressState, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/isAgcEnable"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::isAgcEnabled, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAgcState/{state: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setAgcState, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/muteDtmf/{state: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::muteDtmf, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/isDtmfMuted"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::isDtmfMuted, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/isCaptureMuted"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::isCaptureMuted, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/muteCapture/{state: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::muteCapture, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/isPlaybackMuted"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::isPlaybackMuted, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/mutePlayback/{state: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::mutePlayback, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/isRingtoneMuted"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::isRingtoneMuted, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/muteRingtone/{state: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::muteRingtone, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/audioManager"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAudioManager, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAudioManager/{api: [a-zA-Z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setAudioManager, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/supportedAudioManager"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getSupportedAudioManagers, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/recordPath"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getRecordPath, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setRecordPath/{path: (\\/[a-zA-Z0-9\\.]{1,}){1,}([a-zA-Z0-9]*\\.[a-zA-Z]*)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setRecordPath, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/isAlwaysRecording"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getIsAlwaysRecording, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setIsAlwaysRecording/{status: (true|false)}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setIsAlwaysRecording, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setHistoryLimit/{limit: [0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::setHistoryLimit, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/getHistoryLimit"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getHistoryLimit, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setAccountsOrder"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::setAccountsOrder, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/hookSettings"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getHookSettings, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setHookSettings"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::setHookSettings, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/credentials/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getCredentials, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setCredentials/{accountID: [a-z0-9]*}"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::setCredentials, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/addrFromInterfaceName/{interface: [a-zA-Z0-9]}"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAddrFromInterfaceName, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/allIpInterface"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAllIpInterface, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/allIpInterfaceByName"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getAllIpInterfaceByName, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/shortcuts"); - resources_.back()->set_method_handler("GET", - std::bind(&RestConfigurationManager::getShortcuts, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/setShortcuts"); - resources_.back()->set_method_handler("POST", - std::bind(&RestConfigurationManager::setShortcuts, this, std::placeholders::_1)); -} - -void -RestConfigurationManager::defaultRoute(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /configurationManager", session->get_origin().c_str()); - - std::string body = "Available routes are : \r\n"; - body += "GET /accountDetails/{accountID: [a-z0-9]*}\r\n"; - body += "GET /volatileAccountDetails/{accountID: [a-z0-9]*}\r\n"; - body += "POST /setAccountDetails/{accountID: [a-z0-9]*}\r\n"; - body += "POST /registerName/{accountID: [a-z0-9]*}\r\n"; - body += "GET /setAccountActive/{accountID: [a-z0-9]*}/{status: (true|false)}\r\n"; - body += "GET /accountTemplate/{type: [a-zA-Z]*}\r\n"; - body += "POST /addAccount\r\n"; - body += "GET /removeAccount/{accountID: [a-z0-9]*}\r\n"; - body += "GET /accountList\r\n"; - body += "GET /sendRegister/{accountID: [a-z0-9]*}/{status: (true|false)}\r\n"; - body += "GET /registerAllAccounts\r\n"; - body += "POST /sendTextMessage/{accountID: [a-z0-9]*}/{to: [a-z0-9]*}\r\n"; - body += "GET /messageStatus/{id: [0-9]*}\r\n"; - body += "GET /tlsDefaultSettings\r\n"; - body += "GET /codecList\r\n"; - body += "GET /supportedTlsMethod\r\n"; - body += "GET /supportedCiphers/{accountID: [a-z0-9]*}\r\n"; - body += "GET /codecDetails/{accountID: [a-z0-9]*}/{codecID: [0-9]*}\r\n"; - body += "POST /setCodecDetails/{accountID: [a-z0-9]*}/{codecID: [0-9]*}\r\n"; - body += "GET /activeCodecList/{accountID: [a-z0-9]*}\r\n"; - body += "GET /audioPluginList\r\n"; - body += "GET /setAudioPlugin/{plugin: [a-zA-Z0-9]*}\r\n"; - body += "GET /audioOutputDeviceList\r\n"; - body += "GET /setAudioOutputDevice/{index: [0-9]*}\r\n"; - body += "GET /setAudioInputDevice/{index: [0-9]*}\r\n"; - body += "GET /setAudioRingtoneDevice/{index: [0-9]*}\r\n"; - body += "GET /audioInputDeviceList\r\n"; - body += "GET /currentAudioDeviceIndex\r\n"; - body += "GET /audioInputDeviceIndex/{name: [a-zA-Z0-9]*}\r\n"; - body += "GET /audioOutputDeviceIndex/{name: [a-zA-Z0-9]*}\r\n"; - body += "GET /currentAudioOutputPlugin\r\n"; - body += "GET /noiseSuppressState\r\n"; - body += "GET /setNoiseSuppressState/{state: (true|false)}\r\n"; - body += "GET /isAgcEnable\r\n"; - body += "GET /setAgcState/{state: (true|false)}\r\n"; - body += "GET /muteDtmf/{state: (true|false)}\r\n"; - body += "GET /isDtmfMuted\r\n"; - body += "GET /isCaptureMuted\r\n"; - body += "GET /muteCapture/{state: (true|false)}\r\n"; - body += "GET /isPlaybackMuted\r\n"; - body += "GET /mutePlayback/{state: (true|false)}\r\n"; - body += "GET /isRingtoneMuted\r\n"; - body += "GET /muteRingtone/{state: (true|false)}\r\n"; - body += "GET /audioManager\r\n"; - body += "GET /setAudioManager/{api: [a-zA-Z0-9]*}\r\n"; - body += "GET /supportedAudioManager\r\n"; - body += "GET /isIax2Enable\r\n"; - body += "GET /recordPath\r\n"; - body += "GET /setRecordPath/{path: (\\/[a-zA-Z0-9\\.]{1,}){1,}([a-zA-Z0-9]*\\.[a-zA-Z]*)}\r\n"; - body += "GET /isAlwaysRecording\r\n"; - body += "GET /setIsAlwaysRecording/{status: (true|false)}\r\n"; - body += "GET /setHistoryLimit/{limit: [0-9]*}\r\n"; - body += "GET /getHistoryLimit\r\n"; - body += "POST setAccountsOrder\r\n"; - body += "GET hookSettings\r\n"; - body += "POST setHookSettings\r\n"; - body += "GET credentials/{accountID: [a-z0-9]*}\r\n"; - body += "POST setCredentials/{accountID: [a-z0-9]*}\r\n"; - body += "GET addrFromInterfaceName/{interface: [a-zA-Z0-9]}\r\n"; - body += "GET allIpInterface\r\n"; - body += "GET allIpInterfaceByName\r\n"; - body += "GET shortcuts\r\n"; - body += "POST setShortcuts\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getAccountDetails(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - - JAMI_INFO("[%s] GET /accountDetails/%s", session->get_origin().c_str(), accountID.c_str()); - - std::map<std::string, std::string> accountDetails = DRing::getAccountDetails(accountID); - - std::string body = ""; - - if(accountDetails.size() == 0) - { - session->close(restbed::NOT_FOUND); - } - else - { - for(auto it = std::begin(accountDetails); it != std::end(accountDetails); ++it) - body += it->first + " : " + it->second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); - } -} - -void -RestConfigurationManager::getVolatileAccountDetails(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - - JAMI_INFO("[%s] GET /volatileAccountDetails/%s", session->get_origin().c_str(), accountID.c_str()); - - std::map<std::string, std::string> volatileAccountDetails = DRing::getAccountDetails(accountID); - - std::string body = ""; - - if(volatileAccountDetails.size() == 0) - { - session->close(restbed::NOT_FOUND); - } - else - { - for(auto it = std::begin(volatileAccountDetails); it != std::end(volatileAccountDetails); ++it) - body += it->first + " : " + it->second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); - } -} - -void -RestConfigurationManager::setAccountDetails(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - JAMI_INFO("[%s] POST /setAccountDetails/%s", session->get_origin().c_str(), accountID.c_str()); - - session->fetch(content_length, [this, request, accountID](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - - std::map<std::string, std::string> details = parsePost(data); - JAMI_DBG("Details received"); - for(auto& it : details) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - DRing::setAccountDetails(accountID, details); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::registerName(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - size_t content_length = request->get_header("Content-Length", 0); - - JAMI_INFO("[%s] POST /registerName/%s", session->get_origin().c_str(), accountID.c_str()); - if(content_length > 0){ - session->fetch(content_length, [this, request, accountID](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - - std::map<std::string, std::string> details = parsePost(data); - JAMI_DBG("Details received"); - for(auto& it : details) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - if (details.find("password") == details.end() ){ - session->close(400, "password parameter required"); - return; - } - if (details.find("name") == details.end() ){ - session->close(400, "name parameter required"); - return; - } - - auto response = DRing::registerName(accountID, details["password"], details["name"]); - - session->close(restbed::OK, (response ? "TRUE" : "FALSE")); - }); - } - else { - session->close(400, "empty request"); - } -} - -void -RestConfigurationManager::addPendingNameResolutions(const std::string& name, const std::shared_ptr<restbed::Session> session){ - std::lock_guard<std::mutex> lck(pendingNameResolutionMtx); - this->pendingNameResolutions.insert(std::make_pair(name, session)); -} - -std::set<std::shared_ptr<restbed::Session>> -RestConfigurationManager::getPendingNameResolutions(const std::string& name){ - std::lock_guard<std::mutex> lck(pendingNameResolutionMtx); - - auto result = this->pendingNameResolutions.equal_range(name); - std::set<std::shared_ptr<restbed::Session>> resultSet; - for (auto it = result.first; it != result.second; ++it){ - resultSet.insert(it->second); - } - this->pendingNameResolutions.erase(result.first, result.second); - - return resultSet; -} - -void -RestConfigurationManager::lookupName(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string name = request->get_path_parameter("name"); - - JAMI_WARN("[%s] GET /lookupName/%s", session->get_origin().c_str(), name.c_str()); - - addPendingNameResolutions(name, session); - DRing::lookupName("", "", name); -} - -void -RestConfigurationManager::setAccountActive(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - auto path = request->get_path_parameters(); - - const std::string accountID = request->get_path_parameter("accountID"); - const bool active = (request->get_path_parameter("status") == "true" ? true : false); - - JAMI_INFO("[%s] GET /setAccountActive/%s/%s", session->get_origin().c_str(), accountID.c_str(), (active ? "true" : "false")); - - DRing::setAccountActive(accountID, active); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::getAccountTemplate(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountType = request->get_path_parameter("type"); - - JAMI_INFO("[%s] GET /accountTemplate/%s", session->get_origin().c_str(), accountType.c_str()); - - std::map<std::string, std::string> accountTemplate = DRing::getAccountTemplate(accountType);; - - std::string body = ""; - - for(auto it = std::begin(accountTemplate); it != std::end(accountTemplate); ++it) - body += it->first + " : " + it->second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::addAccount(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - JAMI_INFO("[%s] POST /addAccount", session->get_origin().c_str()); - - session->fetch(content_length, [this, request](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - - std::map<std::string, std::string> details = parsePost(data); - JAMI_DBG("Details received"); - for(auto& it : details) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - DRing::addAccount(details); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::removeAccount(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - - JAMI_INFO("[%s] GET /removeAccount/%s", session->get_origin().c_str(), accountID.c_str()); - - DRing::removeAccount(accountID); - - // TODO : found a way to know if there's no accound with this id, and send a 404 NOT FOUND - // See account_factory.cpp:102 for the function - session->close(restbed::OK); -} - -void -RestConfigurationManager::getAccountList(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /accountList", session->get_origin().c_str()); - - std::vector<std::string> accountList = DRing::getAccountList(); - - std::string body = ""; - - for(auto& it : accountList) - { - body += "accountID : "; - body += it; - body += '\n'; - } - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::sendRegister(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - auto path = request->get_path_parameters(); - - const std::string accountID = request->get_path_parameter("accountID"); - const bool enable = (request->get_path_parameter("status") == "true" ? true : false); - - JAMI_INFO("[%s] GET /sendRegister/%s/%s", session->get_origin().c_str(), accountID.c_str(), (enable ? "true" : "false")); - - DRing::sendRegister(accountID, enable); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::registerAllAccounts(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /registerAllAccounts", session->get_origin().c_str()); - - DRing::registerAllAccounts(); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::sendTextMessage(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - const std::string to = request->get_path_parameter("to"); - - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - JAMI_INFO("[%s] POST /sendTextMessage/%s/%s", session->get_origin().c_str(), accountID.c_str(), to.c_str()); - - session->fetch(content_length, [this, request, accountID, to](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - std::map<std::string, std::string> payloads = parsePost(data); - JAMI_DBG("Payloads received"); - for(auto& it : payloads) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - DRing::sendAccountTextMessage(accountID, to, payloads); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::getMessageStatus(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string id = request->get_path_parameter("id"); - - JAMI_INFO("[%s] GET /messageStatus/%s", session->get_origin().c_str(), id.c_str()); - - const std::uint64_t status = DRing::getMessageStatus(std::stoull(id)); - - std::string body = ""; - - if (status != static_cast<int>(jami::im::MessageStatus::UNKNOWN)) { - switch (status) { - case static_cast<int>(jami::im::MessageStatus::IDLE): - case static_cast<int>(jami::im::MessageStatus::SENDING): - body = "SENDING"; - break; - case static_cast<int>(jami::im::MessageStatus::SENT): - body = "SENT"; - break; - case static_cast<int>(jami::im::MessageStatus::READ): - body = "READ"; - break; - case static_cast<int>(jami::im::MessageStatus::FAILURE): - body = "FAILURE"; - break; - default: - body = "UNKNOWN"; - break; - } - } - else - { - body = "UNKNOWN"; - } - - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getTlsDefaultSettings(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /tlsDefaultSettings", session->get_origin().c_str()); - - std::map<std::string, std::string> tlsDefault = DRing::getTlsDefaultSettings(); - - std::string body = ""; - - for(auto it = std::begin(tlsDefault); it != std::end(tlsDefault); ++it) - body += it->first + " : " + it->second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getCodecList(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /codecList", session->get_origin().c_str()); - - std::vector<unsigned> codec = DRing::getCodecList(); - - std::string body = ""; - - for(auto& it : codec) - body += std::to_string(it) + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getSupportedTlsMethod(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /supportedTlsMethod", session->get_origin().c_str()); - - std::vector<std::string> supported = DRing::getSupportedTlsMethod(); - - std::string body = ""; - - for(auto& it : supported) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getSupportedCiphers(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - - JAMI_INFO("[%s] GET /supportedCiphers/%s", session->get_origin().c_str(), accountID.c_str()); - - std::vector<std::string> supported = DRing::getSupportedCiphers(accountID); - - std::string body = ""; - - for(auto& it : supported) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getCodecDetails(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - const std::string codecID = request->get_path_parameter("codecID"); - - JAMI_INFO("[%s] GET /codecDetails/%s/%s", session->get_origin().c_str(), accountID.c_str(), codecID.c_str()); - - std::map<std::string, std::string> details = DRing::getCodecDetails(accountID, std::stoi(codecID)); - - std::string body = ""; - - for(auto& it : details) - body += it.first + " : " + it.second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setCodecDetails(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - const std::string codecID = request->get_path_parameter("codecID"); - - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - JAMI_INFO("[%s] POST /setCodecDetails/%s/%s", session->get_origin().c_str(), accountID.c_str(), codecID.c_str()); - - session->fetch(content_length, [this, request, accountID, codecID](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - std::map<std::string, std::string> details = parsePost(data); - - JAMI_DBG("Details received"); - for(auto& it : details) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - DRing::setCodecDetails(accountID, std::stoi(codecID), details); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::getActiveCodecList(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - - JAMI_INFO("[%s] GET /activeCodecList/%s", session->get_origin().c_str(), accountID.c_str()); - - std::vector<unsigned> codecs = DRing::getActiveCodecList(accountID); - - std::string body = ""; - - for(auto& it : codecs) - body += std::to_string(it) + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setActiveCodecList(const std::string& accountID, const std::vector<unsigned>& list) -{ - // See restconfigurationmanager.h:70 - - //DRing::setActiveCodecList(accountID, list); -} - -void -RestConfigurationManager::getAudioPluginList(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /audioPluginList", session->get_origin().c_str()); - - std::vector<std::string> list = DRing::getAudioPluginList(); - - std::string body = ""; - - for(auto& it : list) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setAudioPlugin(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string plugin = request->get_path_parameter("plugin"); - - JAMI_INFO("[%s] GET /setAudioPlugin/%s", session->get_origin().c_str(), plugin.c_str()); - - DRing::setAudioPlugin(plugin); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::getAudioOutputDeviceList(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /audioOutputDeviceList", session->get_origin().c_str()); - - std::vector<std::string> list = DRing::getAudioOutputDeviceList(); - - std::string body = ""; - - for(auto& it : list) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setAudioOutputDevice(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string index = request->get_path_parameter("index"); - - JAMI_INFO("[%s] GET /setAudioOutputDevice/%s", session->get_origin().c_str(), index.c_str()); - - DRing::setAudioOutputDevice(std::stoi(index)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::setAudioInputDevice(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string index = request->get_path_parameter("index"); - - JAMI_INFO("[%s] GET /setAudioInputDevice/%s", session->get_origin().c_str(), index.c_str()); - - DRing::setAudioInputDevice(std::stoi(index)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::setAudioRingtoneDevice(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string index = request->get_path_parameter("index"); - - JAMI_INFO("[%s] GET /setAudioRingtoneDevice/%s", session->get_origin().c_str(), index.c_str()); - - DRing::setAudioRingtoneDevice(std::stoi(index)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::getAudioInputDeviceList(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /audioInputDeviceList", session->get_origin().c_str()); - - std::vector<std::string> list = DRing::getAudioInputDeviceList(); - - std::string body = ""; - - for(auto& it : list) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getCurrentAudioDevicesIndex(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /currentAudioDevicesIndex", session->get_origin().c_str()); - - std::vector<std::string> list = DRing::getCurrentAudioDevicesIndex(); - - std::string body = ""; - - for(auto& it : list) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getAudioInputDeviceIndex(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string name = request->get_path_parameter("name"); - - JAMI_INFO("[%s] GET /audioInputDeviceIndex/%s", session->get_origin().c_str(), name.c_str()); - - std::int32_t index = DRing::getAudioInputDeviceIndex(name); - - std::string body = std::to_string(index) + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getAudioOutputDeviceIndex(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string name = request->get_path_parameter("name"); - - JAMI_INFO("[%s] GET /audioOutputDeviceIndex/%s", session->get_origin().c_str(), name.c_str()); - - std::int32_t index = DRing::getAudioOutputDeviceIndex(name); - - std::string body = std::to_string(index) + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getCurrentAudioOutputPlugin(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /currentAudioOutputPlugin", session->get_origin().c_str()); - - std::string body = DRing::getCurrentAudioOutputPlugin(); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getNoiseSuppressState(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /noiseSuppressState", session->get_origin().c_str()); - - std::string body = (DRing::getNoiseSuppressState() ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setNoiseSuppressState(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string state = request->get_path_parameter("state"); - - JAMI_INFO("[%s] GET /setNoiseSuppressState/%s", session->get_origin().c_str(), state.c_str()); - - DRing::setNoiseSuppressState((state == "true" ? true : false)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::isAgcEnabled(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /isAgcEnable", session->get_origin().c_str()); - - bool status = DRing::isAgcEnabled(); - std::string body = (status ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setAgcState(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string state = request->get_path_parameter("state"); - - JAMI_INFO("[%s] GET /setAgcState/%s", session->get_origin().c_str(), state.c_str()); - - DRing::setAgcState((state == "true" ? true : false)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::muteDtmf(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string state = request->get_path_parameter("state"); - - JAMI_INFO("[%s] GET /muteDtmf/%s", session->get_origin().c_str(), state.c_str()); - - DRing::muteDtmf((state == "true" ? true : false)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::isDtmfMuted(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /isDtmfMuted", session->get_origin().c_str()); - - bool status = DRing::isDtmfMuted(); - std::string body = (status ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::isCaptureMuted(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /isCaptureMuted", session->get_origin().c_str()); - - bool status = DRing::isCaptureMuted(); - std::string body = (status ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::muteCapture(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string state = request->get_path_parameter("state"); - - JAMI_INFO("[%s] GET /muteCapture/%s", session->get_origin().c_str(), state.c_str()); - - DRing::muteCapture((state == "true" ? true : false)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::isPlaybackMuted(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /isPlaybackMuted", session->get_origin().c_str()); - - bool status = DRing::isPlaybackMuted(); - std::string body = (status ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::mutePlayback(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string state = request->get_path_parameter("state"); - - JAMI_INFO("[%s] GET /mutePlayback/%s", session->get_origin().c_str(), state.c_str()); - - DRing::mutePlayback((state == "true" ? true : false)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::isRingtoneMuted(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /isRingtoneMuted", session->get_origin().c_str()); - - bool status = DRing::isRingtoneMuted(); - std::string body = (status ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::muteRingtone(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string state = request->get_path_parameter("state"); - - JAMI_INFO("[%s] GET /muteRingtone/%s", session->get_origin().c_str(), state.c_str()); - - DRing::muteRingtone((state == "true" ? true : false)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::getAudioManager(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /audioManager", session->get_origin().c_str()); - - std::string body = DRing::getAudioManager(); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setAudioManager(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string api = request->get_path_parameter("api"); - - JAMI_INFO("[%s] GET /setAudioManager/%s", session->get_origin().c_str(), api.c_str()); - - bool status = DRing::setAudioManager(api); - std::string body = (status ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getSupportedAudioManagers(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - - JAMI_INFO("[%s] GET /supportedAudioManager", session->get_origin().c_str()); - - std::string body = ""; -#if HAVE_ALSA - body += ALSA_API_STR + "\r\n", -#endif -#if HAVE_PULSE - body += PULSEAUDIO_API_STR + "\r\n", -#endif -#if HAVE_JACK - body += JACK_API_STR + "\r\n", -#endif - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getRecordPath(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /recordPath", session->get_origin().c_str()); - - std::string body = DRing::getRecordPath(); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setRecordPath(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string path = request->get_path_parameter("path"); - - JAMI_INFO("[%s] GET /setRecordPath/%s", session->get_origin().c_str(), path.c_str()); - - DRing::setRecordPath(path); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::getIsAlwaysRecording(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /isAlwaysRecording", session->get_origin().c_str()); - - bool status = DRing::getIsAlwaysRecording(); - std::string body = (status ? "true" : "false"); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setIsAlwaysRecording(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string state = request->get_path_parameter("state"); - - JAMI_INFO("[%s] GET /setIsAlwaysRecording/%s", session->get_origin().c_str(), state.c_str()); - - DRing::setIsAlwaysRecording((state == "true" ? true : false)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::setHistoryLimit(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string days = request->get_path_parameter("limit"); - - JAMI_INFO("[%s] GET /setHistoryLimit/%s", session->get_origin().c_str(), days.c_str()); - - DRing::setHistoryLimit(std::stoi(days)); - - session->close(restbed::OK); -} - -void -RestConfigurationManager::getHistoryLimit(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /getHistoryLimit", session->get_origin().c_str()); - - std::string body = std::to_string(DRing::getHistoryLimit()); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setAccountsOrder(const std::shared_ptr<restbed::Session> session) -{ - // POST order=accountID/accountID/ (etc) - - const auto request = session->get_request(); - - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - JAMI_INFO("[%s] POST /setAccountsOrder", session->get_origin().c_str()); - - session->fetch(content_length, [this](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - - std::map<std::string, std::string> details = parsePost(data); - JAMI_DBG("Order received"); - for(auto& it : details) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - std::regex order("[a-z0-9]{16}\\/"); - - auto search = details.find("order"); - if(search != details.end() && std::regex_match(details["order"], order)) - DRing::setAccountsOrder(details["order"]); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::getHookSettings(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /hookSettings", session->get_origin().c_str()); - - std::map<std::string, std::string> hooks = DRing::getHookSettings(); - - std::string body = ""; - - for(auto& it : hooks) - body += it.first + " : " + it.second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setHookSettings(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - JAMI_INFO("[%s] POST /setHookSettings", session->get_origin().c_str()); - - session->fetch(content_length, [this](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - - std::map<std::string, std::string> settings = parsePost(data); - JAMI_DBG("Settings received"); - for(auto& it : settings) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - DRing::setHookSettings(settings); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::getCredentials(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - - JAMI_INFO("[%s] GET /credentials/%s", session->get_origin().c_str(), accountID.c_str()); - - std::vector<std::map<std::string, std::string>> credentials = DRing::getCredentials(accountID); - - std::string body = ""; - - for(auto& it : credentials) - for(auto& i : it) - body += i.first + " : " + i.second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setCredentials(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string accountID = request->get_path_parameter("accountID"); - - JAMI_INFO("[%s] POST /setCredentials/%s", session->get_origin().c_str(), accountID.c_str()); - - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - session->fetch(content_length, [this, accountID](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - - std::map<std::string, std::string> details = parsePost(data); - JAMI_DBG("Details received"); - for(auto& it : details) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - DRing::setCredentials(accountID, std::vector<std::map<std::string, std::string>>{details}); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::getAddrFromInterfaceName(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - const std::string interface = request->get_path_parameter("interface"); - - JAMI_INFO("[%s] GET /addrFromInterfaceName/%s", session->get_origin().c_str(), interface.c_str()); - - std::string body = DRing::getAddrFromInterfaceName(interface); - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getAllIpInterface(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /allIpInterface", session->get_origin().c_str()); - - std::vector<std::string> interfaces = DRing::getAllIpInterface(); - - std::string body = ""; - - for(auto& it : interfaces) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getAllIpInterfaceByName(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /allIpInterfaceByName", session->get_origin().c_str()); - - std::vector<std::string> interfaces = DRing::getAllIpInterfaceByName(); - - std::string body = ""; - - for(auto& it : interfaces) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::getShortcuts(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /shortcuts", session->get_origin().c_str()); - - std::map<std::string, std::string> shortcuts = DRing::getShortcuts(); - - std::string body = ""; - - for(auto& it : shortcuts) - body += it.first + " : " + it.second + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void -RestConfigurationManager::setShortcuts(const std::shared_ptr<restbed::Session> session) -{ - const auto request = session->get_request(); - - JAMI_INFO("[%s] POST /setShortcuts", session->get_origin().c_str()); - - size_t content_length = 0; - request->get_header("Content-Length", content_length); - - session->fetch(content_length, [this](const std::shared_ptr<restbed::Session> session, const restbed::Bytes & body) - { - std::string data(std::begin(body), std::end(body)); - - std::map<std::string, std::string> shortcutsMap = parsePost(data); - JAMI_DBG("shortcutsMap received"); - for(auto& it : shortcutsMap) - JAMI_DBG("%s : %s", it.first.c_str(), it.second.c_str()); - - DRing::setShortcuts(shortcutsMap); - - session->close(restbed::OK); - }); -} - -void -RestConfigurationManager::setVolume(const std::string& device, const double& value) -{ - DRing::setVolume(device, value); -} - -void -RestConfigurationManager::getVolume(const std::string& device) -{ - //return DRing::getVolume(device); -} - -void -RestConfigurationManager::validateCertificate(const std::string& accountId, const std::string& certificate) -{ - //return DRing::validateCertificate(accountId, certificate); -} - -void -RestConfigurationManager::validateCertificatePath(const std::string& accountId, const std::string& certificate, const std::string& privateKey, const std::string& privateKeyPass, const std::string& caList) -{ - //return DRing::validateCertificatePath(accountId, certificate, privateKey, privateKeyPass, caList); -} - -void -RestConfigurationManager::getCertificateDetails(const std::string& certificate) -{ - //return DRing::getCertificateDetails(certificate); -} - -void -RestConfigurationManager::getCertificateDetailsPath(const std::string& certificate, const std::string& privateKey, const std::string& privateKeyPass) -{ - //return DRing::getCertificateDetailsPath(certificate, privateKey, privateKeyPass); -} - -void -RestConfigurationManager::getPinnedCertificates() -{ - //return DRing::getPinnedCertificates(); -} - -void -RestConfigurationManager::pinCertificate(const std::vector<uint8_t>& certificate, const bool& local) -{ - //return DRing::pinCertificate(certificate, local); -} - -void -RestConfigurationManager::pinCertificatePath(const std::string& certPath) -{ - //return DRing::pinCertificatePath(certPath); -} - -void -RestConfigurationManager::unpinCertificate(const std::string& certId) -{ - //return DRing::unpinCertificate(certId); -} - -void -RestConfigurationManager::unpinCertificatePath(const std::string& p) -{ - //return DRing::unpinCertificatePath(p); -} - -void -RestConfigurationManager::pinRemoteCertificate(const std::string& accountId, const std::string& certId) -{ - //return DRing::pinRemoteCertificate(accountId, certId); -} - -void -RestConfigurationManager::setCertificateStatus(const std::string& accountId, const std::string& certId, const std::string& status) -{ - //return DRing::setCertificateStatus(accountId, certId, status); -} - -void -RestConfigurationManager::getCertificatesByStatus(const std::string& accountId, const std::string& status) -{ - //return DRing::getCertificatesByStatus(accountId, status); -} - -void -RestConfigurationManager::getTrustRequests(const std::shared_ptr<restbed::Session> session) -{ - //return DRing::getTrustRequests(accountId); -} - -void -RestConfigurationManager::acceptTrustRequest(const std::string& accountId, const std::string& from) -{ - //return DRing::acceptTrustRequest(accountId, from); -} - -void -RestConfigurationManager::discardTrustRequest(const std::string& accountId, const std::string& from) -{ - //return DRing::discardTrustRequest(accountId, from); -} - -void -RestConfigurationManager::sendTrustRequest(const std::string& accountId, const std::string& to, const std::vector<uint8_t>& payload) -{ - DRing::sendTrustRequest(accountId, to, payload); -} - -void -RestConfigurationManager::exportAccounts(const std::vector<std::string>& accountIDs, const std::string& filepath, const std::string& password) -{ - //return DRing::exportAccounts(accountIDs, filepath, password); -} - -void -RestConfigurationManager::importAccounts(const std::string& archivePath, const std::string& password) -{ - //return DRing::importAccounts(archivePath, password); -} diff --git a/bin/restcpp/restconfigurationmanager.h b/bin/restcpp/restconfigurationmanager.h deleted file mode 100644 index fb1e716db87865e5d42a6a7a5bcb349d3cbd6ca8..0000000000000000000000000000000000000000 --- a/bin/restcpp/restconfigurationmanager.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2016-2019 Savoir-faire Linux Inc. - * - * Author: Simon Zeni <simon.zeni@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#pragma once - -#include <vector> -#include <map> -#include <string> -#include <regex> -#include <restbed> -#include <mutex> - -#if __GNUC__ >= 5 || (__GNUC__ >=4 && __GNUC_MINOR__ >= 6) -/* This warning option only exists for gcc 4.6.0 and greater. */ -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#endif - -#include "dring/dring.h" -#include "dring/callmanager_interface.h" -#include "dring/configurationmanager_interface.h" -#include "dring/presencemanager_interface.h" -#ifdef ENABLE_VIDEO -#include "dring/videomanager_interface.h" -#endif -#include "logger.h" -#include "im/message_engine.h" - -#pragma GCC diagnostic warning "-Wignored-qualifiers" - -#if __GNUC__ >= 5 || (__GNUC__ >=4 && __GNUC_MINOR__ >= 6) -/* This warning option only exists for gcc 4.6.0 and greater. */ -#pragma GCC diagnostic warning "-Wunused-but-set-variable" -#endif - -class RestConfigurationManager -{ - public: - RestConfigurationManager(); - - std::vector<std::shared_ptr<restbed::Resource>> getResources(); - - std::set<std::shared_ptr<restbed::Session>> getPendingNameResolutions(const std::string& name); - - - private: - // Attributes - std::vector<std::shared_ptr<restbed::Resource>> resources_; - std::multimap<std::string, std::shared_ptr<restbed::Session>> pendingNameResolutions; - std::mutex pendingNameResolutionMtx; - // Methods - std::map<std::string, std::string> parsePost(const std::string& post); - void populateResources(); - void addPendingNameResolutions(const std::string& name, const std::shared_ptr<restbed::Session> session); - void defaultRoute(const std::shared_ptr<restbed::Session> session); - - - void getAccountDetails(const std::shared_ptr<restbed::Session> session); - void getVolatileAccountDetails(const std::shared_ptr<restbed::Session> session); - void setAccountDetails(const std::shared_ptr<restbed::Session> session); - void registerName(const std::shared_ptr<restbed::Session> session); - void lookupName(const std::shared_ptr<restbed::Session> session); - void setAccountActive(const std::shared_ptr<restbed::Session> session); - void getAccountTemplate(const std::shared_ptr<restbed::Session> session); - void addAccount(const std::shared_ptr<restbed::Session> session); - void removeAccount(const std::shared_ptr<restbed::Session> session); - void getAccountList(const std::shared_ptr<restbed::Session> session); - void sendRegister(const std::shared_ptr<restbed::Session> session); - void registerAllAccounts(const std::shared_ptr<restbed::Session> session); - void sendTextMessage(const std::shared_ptr<restbed::Session> session); - void getMessageStatus(const std::shared_ptr<restbed::Session> session); - void getTlsDefaultSettings(const std::shared_ptr<restbed::Session> session); - void getCodecList(const std::shared_ptr<restbed::Session> session); - void getSupportedTlsMethod(const std::shared_ptr<restbed::Session> session); - void getSupportedCiphers(const std::shared_ptr<restbed::Session> session); - void getCodecDetails(const std::shared_ptr<restbed::Session> session); - void setCodecDetails(const std::shared_ptr<restbed::Session> session); - void getActiveCodecList(const std::shared_ptr<restbed::Session> session); - void setActiveCodecList(const std::string& accountID, const std::vector<unsigned>& list); // /!\ not implemented - void getAudioPluginList(const std::shared_ptr<restbed::Session> session); - void setAudioPlugin(const std::shared_ptr<restbed::Session> session); - void getAudioOutputDeviceList(const std::shared_ptr<restbed::Session> session); - void setAudioOutputDevice(const std::shared_ptr<restbed::Session> session); - void setAudioInputDevice(const std::shared_ptr<restbed::Session> session); - void setAudioRingtoneDevice(const std::shared_ptr<restbed::Session> session); - void getAudioInputDeviceList(const std::shared_ptr<restbed::Session> session); - void getCurrentAudioDevicesIndex(const std::shared_ptr<restbed::Session> session); - void getAudioInputDeviceIndex(const std::shared_ptr<restbed::Session> session); - void getAudioOutputDeviceIndex(const std::shared_ptr<restbed::Session> session); - void getCurrentAudioOutputPlugin(const std::shared_ptr<restbed::Session> session); - void getNoiseSuppressState(const std::shared_ptr<restbed::Session> session); - void setNoiseSuppressState(const std::shared_ptr<restbed::Session> session); - void isAgcEnabled(const std::shared_ptr<restbed::Session> session); - void setAgcState(const std::shared_ptr<restbed::Session> session); - void muteDtmf(const std::shared_ptr<restbed::Session> session); - void isDtmfMuted(const std::shared_ptr<restbed::Session> session); - void isCaptureMuted(const std::shared_ptr<restbed::Session> session); - void muteCapture(const std::shared_ptr<restbed::Session> session); - void isPlaybackMuted(const std::shared_ptr<restbed::Session> session); - void mutePlayback(const std::shared_ptr<restbed::Session> session); - void isRingtoneMuted(const std::shared_ptr<restbed::Session> session); - void muteRingtone(const std::shared_ptr<restbed::Session> session); - void getAudioManager(const std::shared_ptr<restbed::Session> session); - void setAudioManager(const std::shared_ptr<restbed::Session> session); - void getSupportedAudioManagers(const std::shared_ptr<restbed::Session> session); - void getRecordPath(const std::shared_ptr<restbed::Session> session); - void setRecordPath(const std::shared_ptr<restbed::Session> session); - void getIsAlwaysRecording(const std::shared_ptr<restbed::Session> session); - void setIsAlwaysRecording(const std::shared_ptr<restbed::Session> session); - void setHistoryLimit(const std::shared_ptr<restbed::Session> session); - void getHistoryLimit(const std::shared_ptr<restbed::Session> session); - void setAccountsOrder(const std::shared_ptr<restbed::Session> session); - void getHookSettings(const std::shared_ptr<restbed::Session> session); - void setHookSettings(const std::shared_ptr<restbed::Session> session); - void getCredentials(const std::shared_ptr<restbed::Session> session); - void setCredentials(const std::shared_ptr<restbed::Session> session); - void getAddrFromInterfaceName(const std::shared_ptr<restbed::Session> session); - void getAllIpInterface(const std::shared_ptr<restbed::Session> session); - void getAllIpInterfaceByName(const std::shared_ptr<restbed::Session> session); - void getShortcuts(const std::shared_ptr<restbed::Session> session); - void setShortcuts(const std::shared_ptr<restbed::Session> session); - void setVolume(const std::string& device, const double& value); - void getVolume(const std::string& device); - void validateCertificate(const std::string& accountId, const std::string& certificate); - void validateCertificatePath(const std::string& accountId, const std::string& certificatePath, const std::string& privateKey, const std::string& privateKeyPass, const std::string& caList); - void getCertificateDetails(const std::string& certificate); - void getCertificateDetailsPath(const std::string& certificatePath, const std::string& privateKey, const std::string& privateKeyPass); - void getPinnedCertificates(); - void pinCertificate(const std::vector<uint8_t>& certificate, const bool& local); - void unpinCertificate(const std::string& certId); - void pinCertificatePath(const std::string& path); - void unpinCertificatePath(const std::string& path); - void pinRemoteCertificate(const std::string& accountId, const std::string& certId); - void setCertificateStatus(const std::string& account, const std::string& certId, const std::string& status); - void getCertificatesByStatus(const std::string& account, const std::string& status); - void getTrustRequests(const std::shared_ptr<restbed::Session> session); - void acceptTrustRequest(const std::string& accountId, const std::string& from); - void discardTrustRequest(const std::string& accountId, const std::string& from); - void sendTrustRequest(const std::string& accountId, const std::string& to, const std::vector<uint8_t>& payload); - void exportAccounts(const std::vector<std::string>& accountIDs, const std::string& filepath, const std::string& password); - void importAccounts(const std::string& archivePath, const std::string& password); -}; diff --git a/bin/restcpp/restvideomanager.cpp b/bin/restcpp/restvideomanager.cpp deleted file mode 100644 index 74080458f625a2013d0f73e52ce61a17b822b2ea..0000000000000000000000000000000000000000 --- a/bin/restcpp/restvideomanager.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2016-2019 Savoir-faire Linux Inc. - * - * Author: Simon Zeni <simon.zeni@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include "restvideomanager.h" -#include "client/videomanager.h" - -RestVideoManager::RestVideoManager() : - resources_() -{ - populateResources(); -} - -std::vector<std::shared_ptr<restbed::Resource>> -RestVideoManager::getResources() -{ - return resources_; -} - -// Private - -std::map<std::string, std::string> -RestVideoManager::parsePost(const std::string& post) -{ - std::map<std::string, std::string> data; - - auto split = [](const std::string& s, char delim){ - std::vector<std::string> v; - auto i = 0; - auto pos = s.find(delim); - while (pos != std::string::npos) - { - v.push_back(s.substr(i, pos-i)); - i = ++pos; - pos = s.find(delim, pos); - - if (pos == std::string::npos) - v.push_back(s.substr(i, s.length())); - } - - return v; - }; - - if(post.find_first_of('&') != std::string::npos) - { - std::vector<std::string> v = split(post, '&'); - - for(auto& it : v) - { - std::vector<std::string> tmp = split(it, '='); - data[tmp.front()] = tmp.back(); - } - } - else - { - std::vector<std::string> tmp = split(post, '='); - data[tmp.front()] = tmp.back(); - } - - return data; -} - -void -RestVideoManager::populateResources() -{ - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/videoManager"); - resources_.back()->set_method_handler("GET", - std::bind(&RestVideoManager::defaultRoute, this, std::placeholders::_1)); - - resources_.push_back(std::make_shared<restbed::Resource>()); - resources_.back()->set_path("/deviceList"); - resources_.back()->set_method_handler("GET", - std::bind(&RestVideoManager::getDeviceList, this, std::placeholders::_1)); -} - -void -RestVideoManager::defaultRoute(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /videoManager", session->get_origin().c_str()); - - std::string body = "Available routes are : \r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); -} - -void RestVideoManager::getDeviceList(const std::shared_ptr<restbed::Session> session) -{ - JAMI_INFO("[%s] GET /deviceList", session->get_origin().c_str()); - std::vector<std::string> list = DRing::getDeviceList(); - - std::string body = ""; - - for(auto& it : list) - body += it + "\r\n"; - - const std::multimap<std::string, std::string> headers - { - {"Content-Type", "text/html"}, - {"Content-Length", std::to_string(body.length())} - }; - - session->close(restbed::OK, body, headers); - -} - -void RestVideoManager::getCapabilities(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::getSettings(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::applySettings(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::setDefaultDevice(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::getDefaultDevice(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::startCamera(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::stopCamera(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::switchInput(const std::shared_ptr<restbed::Session> session) -{ - -} - -void RestVideoManager::hasCameraStarted(const std::shared_ptr<restbed::Session> session) -{ - -} diff --git a/bin/restcpp/restvideomanager.h b/bin/restcpp/restvideomanager.h deleted file mode 100644 index 86fc19bab0039a3128b196a9afe9a41b1778d6b8..0000000000000000000000000000000000000000 --- a/bin/restcpp/restvideomanager.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2016-2019 Savoir-faire Linux Inc. - * - * Author: Simon Zeni <simon.zeni@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#pragma once - -#include <vector> -#include <map> -#include <string> -#include <restbed> - -#if __GNUC__ >= 5 || (__GNUC__ >=4 && __GNUC_MINOR__ >= 6) -/* This warning option only exists for gcc 4.6.0 and greater. */ -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#endif - -#include "dring/dring.h" -#include "dring/callmanager_interface.h" -#include "dring/configurationmanager_interface.h" -#include "dring/presencemanager_interface.h" -#ifdef ENABLE_VIDEO -#include "dring/videomanager_interface.h" -#endif -#include "logger.h" - -#if __GNUC__ >= 5 || (__GNUC__ >=4 && __GNUC_MINOR__ >= 6) -/* This warning option only exists for gcc 4.6.0 and greater. */ -#pragma GCC diagnostic warning "-Wunused-but-set-variable" -#endif - -class RestVideoManager -{ - public: - RestVideoManager(); - - std::vector<std::shared_ptr<restbed::Resource>> getResources(); - - private: - // Attributes - std::vector<std::shared_ptr<restbed::Resource>> resources_; - - // Methods - std::map<std::string, std::string> parsePost(const std::string& post); - void populateResources(); - void defaultRoute(const std::shared_ptr<restbed::Session> session); - - void getDeviceList(const std::shared_ptr<restbed::Session> session); - void getCapabilities(const std::shared_ptr<restbed::Session> session); - void getSettings(const std::shared_ptr<restbed::Session> session); - void applySettings(const std::shared_ptr<restbed::Session> session); - void setDefaultDevice(const std::shared_ptr<restbed::Session> session); - void getDefaultDevice(const std::shared_ptr<restbed::Session> session); - void startCamera(const std::shared_ptr<restbed::Session> session); - void stopCamera(const std::shared_ptr<restbed::Session> session); - void switchInput(const std::shared_ptr<restbed::Session> session); - void hasCameraStarted(const std::shared_ptr<restbed::Session> session); -}; diff --git a/configure.ac b/configure.ac index 53bb95210290c42eaf1d0cb700098a466c8a0b48..4464354f14e4d9c9f11880929c7df697519a60b5 100644 --- a/configure.ac +++ b/configure.ac @@ -431,19 +431,9 @@ AS_IF([test "x$with_nodejs" = "xyes"], [ AM_CONDITIONAL(RING_NODEJS, false) ); -# Rest C++ with restbed -AC_ARG_WITH([restcpp], - AS_HELP_STRING([--with-restcpp], [enable rest support with C++])) -AC_ARG_ENABLE([restbed_old_api], AS_HELP_STRING([--enable-restbed-old-api], [Use the old restbed API])) -AS_IF([test "x$enable_restbed_old_api" = "xyes"], [ - AC_DEFINE([RESTBED_OLD_API], [1], [Defined if you use the old restbed API]) -]) - -AS_IF([test "x$enable_ringns" != "xno" || test "x$with_restcpp" = "xyes"], [ - AC_CHECK_LIB(restbed, exit,, AC_MSG_ERROR([Missing restbed files])) +AS_IF([test "x$enable_ringns" != "xno"], [ PKG_CHECK_MODULES(LIBCRYPTO, libcrypto,, AC_MSG_ERROR([Missing libcrypto development files])) PKG_CHECK_MODULES(LIBSSL, libssl,, AC_MSG_ERROR([Missing libssl development files])) - LIBS="${LIBS} -lssl -lcrypto" AS_IF([test "${HAVE_WIN32}" = "1"],[ LIBS="${LIBS} -lssleay32 -leay32" @@ -451,15 +441,6 @@ AS_IF([test "x$enable_ringns" != "xno" || test "x$with_restcpp" = "xyes"], [ ], [] ); -AS_IF([test "x$with_restcpp" = "xyes"], [ - AS_AC_EXPAND(SBINDIR, $sbindir) - AC_SUBST(SBINDIR) - AC_CONFIG_FILES([bin/restcpp/Makefile]) - AM_CONDITIONAL(RING_RESTCPP, true) - ], - AM_CONDITIONAL(RING_RESTCPP, false) -); - dnl Check for libav PKG_CHECK_MODULES(LIBAVUTIL, libavutil >= 54.31.100,, AC_MSG_ERROR([Missing libavutil development files])) diff --git a/contrib/src/asio/rules.mak b/contrib/src/asio/rules.mak index 2548ac161ccba9d02094d54d27bb78cb1a3818f4..d65fbc9e9a907463044f1c26d9b81f61d7010ea2 100644 --- a/contrib/src/asio/rules.mak +++ b/contrib/src/asio/rules.mak @@ -21,7 +21,7 @@ ASIO_VERSION := asio-1-12-2 ASIO_URL := https://github.com/chriskohlhoff/asio/archive/$(ASIO_VERSION).tar.gz -# Pure dependency of restbed: do not add to PKGS. +# Pure dependency of restinio: do not add to PKGS. $(TARBALLS)/asio-$(ASIO_VERSION).tar.gz: $(call download,$(ASIO_URL)) diff --git a/contrib/src/fmt/SHA512SUMS b/contrib/src/fmt/SHA512SUMS new file mode 100644 index 0000000000000000000000000000000000000000..0f8c45a137606e551475d79abc67696c2d86d5ba --- /dev/null +++ b/contrib/src/fmt/SHA512SUMS @@ -0,0 +1 @@ +9ef0f3d328681253c1e1776576d54d67dec49c19fd7fc422ae63c3610b01a3f05f6e83cdf5e913dfd09bac42e52fe35c38ebe1ea91f4207d226a32aaf69eb4a8 fmt-5.3.0.tar.gz diff --git a/contrib/src/fmt/fetch_and_patch.bat b/contrib/src/fmt/fetch_and_patch.bat new file mode 100644 index 0000000000000000000000000000000000000000..3b515fa0dcf6c93376de3ecb308d18b0c61b4cd6 --- /dev/null +++ b/contrib/src/fmt/fetch_and_patch.bat @@ -0,0 +1,20 @@ +set BUILD=%SRC%..\build + +set FMT_VERSION=5.3.0 +set FMT_URL=https://github.com/fmtlib/fmt/archive/%FMT_VERSION%.tar.gz + +mkdir %BUILD% + +if %USE_CACHE%==1 ( + copy %CACHE_DIR%\%FMT_VERSION%.tar.gz %cd% +) else ( + %WGET_CMD% %FMT_URL% +) + +7z -y x %FMT_VERSION%.tar.gz && 7z -y x %FMT_VERSION%.tar -o%BUILD% +del %FMT_VERSION%.tar && del %FMT_VERSION%.tar.gz && del %BUILD%\pax_global_header +rename %BUILD%\fmt-%FMT_VERSION% fmt + +cd %BUILD%\fmt + +cd %SRC% diff --git a/contrib/src/fmt/rules.mak b/contrib/src/fmt/rules.mak new file mode 100644 index 0000000000000000000000000000000000000000..335d9a48886a5ae9da5cd425f9f9798bee9a866a --- /dev/null +++ b/contrib/src/fmt/rules.mak @@ -0,0 +1,28 @@ +# FMT +FMT_VERSION := 5.3.0 +FMT_URL := https://github.com/fmtlib/fmt/archive/$(FMT_VERSION).tar.gz + +PKGS += fmt +ifeq ($(call need_pkg,'fmt'),) +PKGS_FOUND += fmt +endif + +# fmt 5.3.0 fix: https://github.com/fmtlib/fmt/issues/1267 +FMT_CMAKECONF = -DBUILD_SHARED_LIBS=Off -DFMT_USE_USER_DEFINED_LITERALS=0 \ + CMAKE_INSTALL_LIBDIR=$(PREFIX)/lib + +$(TARBALLS)/fmt-$(FMT_VERSION).tar.gz: + $(call download,$(FMT_URL)) + +.sum-fmt: fmt-$(FMT_VERSION).tar.gz + +fmt: fmt-$(FMT_VERSION).tar.gz + $(UNPACK) + $(UPDATE_AUTOCONFIG) && cd $(UNPACK_DIR) + $(MOVE) + +.fmt: fmt toolchain.cmake .sum-fmt + cd $< && $(HOSTVARS) $(CMAKE) $(FMT_CMAKECONF) . + cd $< && $(MAKE) install + cd $< && mv $(PREFIX)/share/pkgconfig/fmt.pc $(PREFIX)/lib/pkgconfig/ + touch $@ diff --git a/contrib/src/http_parser/SHA512SUMS b/contrib/src/http_parser/SHA512SUMS new file mode 100644 index 0000000000000000000000000000000000000000..f0a06387d2ab83fdafc462d46233d67b333e78ea --- /dev/null +++ b/contrib/src/http_parser/SHA512SUMS @@ -0,0 +1 @@ +cbbeb606229488d0136b131e2270c361eeb1663fc302b5206822a4c48b7b398c04457f88d9f61528b565c318a8df526d44293df442c862b486fe3a0f45e45219 http_parser-2.9.3.tar.gz diff --git a/contrib/src/http_parser/fetch_and_patch.bat b/contrib/src/http_parser/fetch_and_patch.bat new file mode 100644 index 0000000000000000000000000000000000000000..430e4915c186eabcc2ea7a5c93e613b96d531f74 --- /dev/null +++ b/contrib/src/http_parser/fetch_and_patch.bat @@ -0,0 +1,20 @@ +set BUILD=%SRC%..\build + +set HTTP_PARSER_VERSION=2.9.3 +set HTTP_PARSER_URL=https://github.com/binarytrails/http_parser/archive/v%HTTP_PARSER_VERSION%.tar.gz + +mkdir %BUILD% + +if %USE_CACHE%==1 ( + copy %CACHE_DIR%\%HTTP_PARSER_VERSION%.tar.gz %cd% +) else ( + %WGET_CMD% %HTTP_PARSER_URL% +) + +7z -y x %HTTP_PARSER_VERSION%.tar.gz && 7z -y x %HTTP_PARSER_VERSION%.tar -o%BUILD% +del %HTTP_PARSER_VERSION%.tar && del %HTTP_PARSER_VERSION%.tar.gz && del %BUILD%\pax_global_header +rename %BUILD%\http_parser-%HTTP_PARSER_VERSION% http_parser + +cd %BUILD%\http_parser + +cd %SRC% diff --git a/contrib/src/http_parser/rules.mak b/contrib/src/http_parser/rules.mak new file mode 100644 index 0000000000000000000000000000000000000000..a7f047ebfe88383287365a36b15a9ff9ae866876 --- /dev/null +++ b/contrib/src/http_parser/rules.mak @@ -0,0 +1,25 @@ +# HTTP_PARSER +HTTP_PARSER_VERSION := 2.9.3 +HTTP_PARSER_URL := https://github.com/binarytrails/http_parser/archive/v$(HTTP_PARSER_VERSION).tar.gz + +PKGS += http_parser +ifeq ($(call need_pkg,'http_parser'),) +PKGS_FOUND += http_parser +endif + +HTTP_PARSER_MAKECONF := PREFIX=$(PREFIX) + +$(TARBALLS)/http_parser-$(HTTP_PARSER_VERSION).tar.gz: + $(call download,$(HTTP_PARSER_URL)) + +.sum-http_parser: http_parser-$(HTTP_PARSER_VERSION).tar.gz + +http_parser: http_parser-$(HTTP_PARSER_VERSION).tar.gz + $(UNPACK) + $(UPDATE_AUTOCONFIG) && cd $(UNPACK_DIR) + $(MOVE) + +.http_parser: http_parser toolchain.cmake .sum-http_parser + cd $< && $(HOSTVARS) $(MAKE) $(HTTP_PARSER_MAKECONF) package + cd $< && cp -f http_parser.h $(PREFIX)/include && cp -f libhttp_parser.a $(PREFIX)/lib + touch $@ diff --git a/contrib/src/libressl/rules.mak b/contrib/src/libressl/rules.mak index 6c4bc418a01b342092ad35793953b6588ffd369b..1c6422b41f17768fa2e0ff3672bdcd00a8ca9c17 100644 --- a/contrib/src/libressl/rules.mak +++ b/contrib/src/libressl/rules.mak @@ -29,7 +29,7 @@ ifeq ($(call need_pkg,"openssl >= 1.0.0" || call need_pkg,"libressl >= 1.0.0"),) PKGS_FOUND += libressl endif -# Pure dependency of restbed: do not add to PKGS. +# Pure dependency of restinio: do not add to PKGS. $(TARBALLS)/portable-$(LIBRESSL_VERSION).tar.gz: $(call download,$(LIBRESSL_URL)) diff --git a/contrib/src/opendht/SHA512SUMS b/contrib/src/opendht/SHA512SUMS index c9ff4d3f1f990f6060fbb0450354244ccebb6539..1cb0016c011f7422081e01c4c28d55d282a491cb 100644 --- a/contrib/src/opendht/SHA512SUMS +++ b/contrib/src/opendht/SHA512SUMS @@ -1 +1 @@ -d0ab4aa376ecd4ac57af78a1491cd0f466021790ebea0e00032a503d61127f323cb37f04d94f2a35797dc52051407708f49ed99be558003acc102ff017dbdf29 opendht-1.10.1.tar.gz \ No newline at end of file +f7b2d051a2c75675ae217ff7cba32cdb12afa7e79371d595e3e0f96d56d52ddff1767190c51362dcda8d36438c5af3a7b9f1cffa2d76a5039bd60ffb9fcef33a opendht-5068de7bc0ff4cb5dba20af4a97415d385949d3d.tar.gz diff --git a/contrib/src/opendht/rules.mak b/contrib/src/opendht/rules.mak index cc7afcbb62781d3bfa2deb88d20540aa7ff22bb8..69d6132a5e297c7c309c5ad245ee8ab5c2581a01 100644 --- a/contrib/src/opendht/rules.mak +++ b/contrib/src/opendht/rules.mak @@ -1,5 +1,5 @@ # OPENDHT -OPENDHT_VERSION := 1.10.1 +OPENDHT_VERSION := 5068de7bc0ff4cb5dba20af4a97415d385949d3d OPENDHT_URL := https://github.com/savoirfairelinux/opendht/archive/$(OPENDHT_VERSION).tar.gz PKGS += opendht @@ -14,8 +14,11 @@ endif ifneq ($(call need_pkg,"libargon2"),) DEPS_opendht += argon2 endif -ifneq ($(call need_pkg,"restbed"),) -DEPS_opendht += restbed +ifneq ($(call need_pkg,"libressl >= 1-12-2"),) +DEPS_opendht += libressl +endif +ifneq ($(call need_pkg,"restinio >= v.0.5.1"),) +DEPS_opendht += restinio endif ifneq ($(call need_pkg,"jsoncpp"),) DEPS_opendht += jsoncpp @@ -24,6 +27,9 @@ ifneq ($(call need_pkg,"gnutls >= 3.3.0"),) DEPS_opendht += gnutls endif +# fmt 5.3.0 fix: https://github.com/fmtlib/fmt/issues/1267 +OPENDHT_CONF = FMT_USE_USER_DEFINED_LITERALS=0 + $(TARBALLS)/opendht-$(OPENDHT_VERSION).tar.gz: $(call download,$(OPENDHT_URL)) @@ -36,6 +42,6 @@ opendht: opendht-$(OPENDHT_VERSION).tar.gz .opendht: opendht .sum-opendht mkdir -p $</m4 && $(RECONF) - cd $< && $(HOSTVARS) ./configure --enable-static --disable-shared --disable-tools --disable-python --disable-doc --enable-proxy-server --enable-proxy-client --enable-push-notifications $(HOSTCONF) + cd $< && $(HOSTVARS) $(OPENDHT_CONF) ./configure --enable-static --disable-shared --disable-tools --disable-python --disable-doc --enable-proxy-server --enable-proxy-client --enable-push-notifications $(HOSTCONF) cd $< && $(MAKE) install touch $@ diff --git a/contrib/src/restbed/SHA512SUMS b/contrib/src/restbed/SHA512SUMS deleted file mode 100644 index 07591231cdb908dad1b23bb8112d67bbdfbd52d4..0000000000000000000000000000000000000000 --- a/contrib/src/restbed/SHA512SUMS +++ /dev/null @@ -1 +0,0 @@ -703d3d25363b52c628479788a634c93a96f91a4df719d70b78610f3eecd1a21888bdc3283983ead22c597abe33b2f96ad82ca953daa5341ce25b3361a7dc720c restbed-58eaf0a1df49917145357f86c87b3f1acadaa66a.tar.gz \ No newline at end of file diff --git a/contrib/src/restbed/asio-uwp.patch b/contrib/src/restbed/asio-uwp.patch deleted file mode 100644 index 7bd416b78e9cc0cb0d5c066a78f866dcfc91cf18..0000000000000000000000000000000000000000 --- a/contrib/src/restbed/asio-uwp.patch +++ /dev/null @@ -1,68 +0,0 @@ ---- a/asio/include/asio/detail/impl/win_iocp_io_context.ipp -+++ b/asio/include/asio/detail/impl/win_iocp_io_context.ipp -@@ -93,7 +93,7 @@ void win_iocp_io_context::shutdown() - { - LARGE_INTEGER timeout; - timeout.QuadPart = 1; -- ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE); -+ //::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE); - } - - while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0) -@@ -477,11 +477,11 @@ DWORD win_iocp_io_context::get_gqcs_timeout() - osvi.dwOSVersionInfoSize = sizeof(osvi); - osvi.dwMajorVersion = 6ul; - -- const uint64_t condition_mask = ::VerSetConditionMask( -+ /*const uint64_t condition_mask = ::VerSetConditionMask( - 0, VER_MAJORVERSION, VER_GREATER_EQUAL); - - if (!!::VerifyVersionInfo(&osvi, VER_MAJORVERSION, condition_mask)) -- return INFINITE; -+ return INFINITE;*/ - - return default_gqcs_timeout; - } -@@ -492,7 +492,7 @@ void win_iocp_io_context::do_add_timer_queue(timer_queue_base& queue) - - timer_queues_.insert(&queue); - -- if (!waitable_timer_.handle) -+ /*if (!waitable_timer_.handle) - { - waitable_timer_.handle = ::CreateWaitableTimer(0, FALSE, 0); - if (waitable_timer_.handle == 0) -@@ -508,7 +508,7 @@ void win_iocp_io_context::do_add_timer_queue(timer_queue_base& queue) - timeout.QuadPart *= 10; - ::SetWaitableTimer(waitable_timer_.handle, - &timeout, max_timeout_msec, 0, 0, FALSE); -- } -+ }*/ - - if (!timer_thread_.get()) - { -@@ -537,8 +537,8 @@ void win_iocp_io_context::update_timeout() - LARGE_INTEGER timeout; - timeout.QuadPart = -timeout_usec; - timeout.QuadPart *= 10; -- ::SetWaitableTimer(waitable_timer_.handle, -- &timeout, max_timeout_msec, 0, 0, FALSE); -+ //::SetWaitableTimer(waitable_timer_.handle, -+ //&timeout, max_timeout_msec, 0, 0, FALSE); - } - } - } ---- a/asio/include/asio/detail/impl/win_thread.ipp -+++ b/asio/include/asio/detail/impl/win_thread.ipp -@@ -46,7 +46,7 @@ void win_thread::join() - ::CloseHandle(exit_event_); - if (terminate_threads()) - { -- ::TerminateThread(thread_, 0); -+ //::TerminateThread(thread_, 0); - } - else - { --- -2.8.1.windows.1 - diff --git a/contrib/src/restbed/fetch_and_patch.bat b/contrib/src/restbed/fetch_and_patch.bat deleted file mode 100644 index 97aabaa27c6da5ec3936f11b3bde15e58d40c0fa..0000000000000000000000000000000000000000 --- a/contrib/src/restbed/fetch_and_patch.bat +++ /dev/null @@ -1,90 +0,0 @@ -set BUILD=%SRC%..\build -mkdir %BUILD% - -set RESTBED_VERSION=bf61912c80572475b83a2fcf0da519f492a4d99e -set RESTBED_URL=https://github.com/Corvusoft/restbed/archive/%RESTBED_VERSION%.tar.gz - -if %USE_CACHE%==1 ( - copy %CACHE_DIR%\%RESTBED_VERSION%.tar.gz %cd% -) else ( - %WGET_CMD% %RESTBED_URL% -) - -rem ------------ restbed ------------ - -7z -y x %RESTBED_VERSION%.tar.gz && 7z -y x %RESTBED_VERSION%.tar -o%BUILD% -del %RESTBED_VERSION%.tar && del %RESTBED_VERSION%.tar.gz && del %BUILD%\pax_global_header -rename %BUILD%\restbed-%RESTBED_VERSION% restbed - -cd %BUILD%\restbed - -%APPLY_CMD% %SRC%\restbed\win32_cmake-find-openssl-shared.patch - -cd .. - -:: submodules - -rmdir /s /q %BUILD%\restbed\dependency -mkdir %BUILD%\restbed\dependency -cd %BUILD%\restbed\dependency - -rem ------------ asio ------------ - -set ASIO_VERSION=276846097ab5073b67e772dbdfa12596224a54a5 -set ASIO_URL=https://github.com/Corvusoft/asio-dependency/archive/%ASIO_VERSION%.tar.gz - -if %USE_CACHE%==1 ( - copy %CACHE_DIR%\%ASIO_VERSION%.tar.gz %cd% -) else ( - %WGET_CMD% %ASIO_URL% -) - -7z -y x %ASIO_VERSION%.tar.gz && 7z -y x %ASIO_VERSION%.tar -del %ASIO_VERSION%.tar && del %ASIO_VERSION%.tar.gz && del pax_global_header -rename asio-dependency-%ASIO_VERSION% asio - -cd asio - -if "%1"=="uwp" ( - %APPLY_CMD% %SRC%\restbed\asio-uwp.patch -) - -cd .. - -rem ------------ catch ------------ - -set CATCH_VERSION=35f510545d55a831372d3113747bf1314ff4f2ef -set CATCH_URL=https://github.com/Corvusoft/catch-dependency/archive/%CATCH_VERSION%.tar.gz - -if %USE_CACHE%==1 ( - copy %CACHE_DIR%\%CATCH_VERSION%.tar.gz %cd% -) else ( - %WGET_CMD% %CATCH_URL% -) - -7z -y x %CATCH_VERSION%.tar.gz && 7z -y x %CATCH_VERSION%.tar -del %CATCH_VERSION%.tar && del %CATCH_VERSION%.tar.gz && del pax_global_header -rename catch-dependency-%CATCH_VERSION% catch - -rem ------------ openssl ------------ - -set OPENSSL_VERSION=5cc1e25bc76bcf0db03bc37bd64b3290727963b6 -set OPENSSL_URL=https://github.com/Microsoft/openssl/archive/%OPENSSL_VERSION%.tar.gz - -if %USE_CACHE%==1 ( - copy %CACHE_DIR%\%OPENSSL_VERSION%.tar.gz %cd% -) else ( - %WGET_CMD% %OPENSSL_URL% -) - -7z -y x %OPENSSL_VERSION%.tar.gz && 7z -y x %OPENSSL_VERSION%.tar -del %OPENSSL_VERSION%.tar && del %OPENSSL_VERSION%.tar.gz && del pax_global_header -rename openssl-%OPENSSL_VERSION% openssl - -cd openssl - -if "%1"=="uwp" ( - %APPLY_CMD% %SRC%\restbed\openssl-uwp.patch -) - -cd %SRC% \ No newline at end of file diff --git a/contrib/src/restbed/openssl-uwp.patch b/contrib/src/restbed/openssl-uwp.patch deleted file mode 100644 index 1b33d2d54be50b5c2c08713bb611027983697052..0000000000000000000000000000000000000000 --- a/contrib/src/restbed/openssl-uwp.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/ms/setVSvars.bat -+++ b/ms/setVSvars.bat -@@ -166,7 +166,7 @@ exit /b - - :set_VS15VC - if not "%_VS15VC%"=="" goto :eof -- for /f "usebackq tokens=1* delims=: " %%i in (`%~dp0\vswhere -latest -requires Microsoft.VisualStudio.Workload.Universal -requires Microsoft.VisualStudio.ComponentGroup.UWP.VC`) do ( -+ for /f "usebackq tokens=1* delims=: " %%i in (`%~dp0\vswhere -latest -requires Microsoft.VisualStudio.Workload.Universal`) do ( - if /i "%%i"=="installationPath" set _VS15VC=%%j\VC\Auxiliary\Build - ) - if not "%_VS15VC%"=="" goto :eof ---- a/ms/winrt.cpp -+++ b/ms/winrt.cpp -@@ -291,13 +291,6 @@ extern "C" - { - return 0; - } -- -- BOOL WINAPI FlushConsoleInputBuffer( -- _In_ HANDLE hConsoleInput -- ) -- { -- return 0; -- } - BOOL DeleteDC( - _In_ HDC hdc - ) --- -2.10.2.windows.1 - diff --git a/contrib/src/restbed/rules.mak b/contrib/src/restbed/rules.mak deleted file mode 100644 index 6bf1ea53aa36c519472d2ed769d094453861baa6..0000000000000000000000000000000000000000 --- a/contrib/src/restbed/rules.mak +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright (C) 2016-2019 Savoir-faire Linux Inc. -# -# Author: Simon Zeni <simon.zeni@savoirfairelinux.com> -# Adrien Béraud <adrien.beraud@savoirfairelinux.com -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3 of the License, or -# (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -RESTBED_VERSION := 58eaf0a1df49917145357f86c87b3f1acadaa66a -RESTBED_URL := https://github.com/aberaud/restbed/archive/$(RESTBED_VERSION).tar.gz - -# Pure dependency of OpenDHT: do not add to PKGS. - -ifeq ($(call need_pkg,"restbed >= 4.0"),) -PKGS_FOUND += restbed -endif - -$(TARBALLS)/restbed-$(RESTBED_VERSION).tar.gz: - $(call download,$(RESTBED_URL)) - -DEPS_restbed = asio libressl - -RESTBED_CONF = -DBUILD_TESTS=NO \ - -DBUILD_SSL=YES \ - -DBUILD_STATIC=YES \ - -DBUILD_SHARED=NO \ - -DCMAKE_INCLUDE_PATH=$(PREFIX)/include \ - -DCMAKE_INSTALL_PREFIX=$(PREFIX) \ - -DCMAKE_INSTALL_LIBDIR=lib - -restbed: restbed-$(RESTBED_VERSION).tar.gz .sum-restbed - $(UNPACK) - $(MOVE) - -.restbed: restbed toolchain.cmake - cd $< && $(HOSTVARS) $(CMAKE) $(RESTBED_CONF) . - cd $< && $(MAKE) install - touch $@ - -.sum-restbed: restbed-$(RESTBED_VERSION).tar.gz diff --git a/contrib/src/restbed/win32_cmake-find-openssl-shared.patch b/contrib/src/restbed/win32_cmake-find-openssl-shared.patch deleted file mode 100644 index 3636cfc41ce16a129fa79129a42276d5a80af871..0000000000000000000000000000000000000000 --- a/contrib/src/restbed/win32_cmake-find-openssl-shared.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/cmake/Findopenssl.cmake -+++ b/cmake/Findopenssl.cmake -@@ -1,8 +1,8 @@ - find_library( ssl_LIBRARY_STATIC libssl.a ssleay32.lib HINTS "${PROJECT_SOURCE_DIR}/dependency/openssl/out32dll" "${PROJECT_SOURCE_DIR}/dependency/openssl" "/usr/local/opt/openssl/lib" "/usr/lib" "/usr/local/lib" "/opt/local/lib" ) - find_library( crypto_LIBRARY_STATIC libcrypto.a libeay32.lib HINTS "${PROJECT_SOURCE_DIR}/dependency/openssl/out32dll" "${PROJECT_SOURCE_DIR}/dependency/openssl" "/usr/local/opt/openssl/lib" "/usr/lib" "/usr/local/lib" "/opt/local/lib" ) - --find_library( ssl_LIBRARY_SHARED libssl.so libssl.dylib ssleay32.dll HINTS "${PROJECT_SOURCE_DIR}/dependency/openssl/out32dll" "${PROJECT_SOURCE_DIR}/dependency/openssl" "/usr/local/opt/openssl/lib" "/usr/lib" "/usr/local/lib" "/opt/local/lib" ) --find_library( crypto_LIBRARY_SHARED libcrypto.so libcrypto.dylib libeay32.dll HINTS "${PROJECT_SOURCE_DIR}/dependency/openssl/out32dll" "${PROJECT_SOURCE_DIR}/dependency/openssl" "/usr/local/opt/openssl/lib" "/usr/lib" "/usr/local/lib" "/opt/local/lib" ) -+find_library( ssl_LIBRARY_SHARED libssl.so libssl.dylib ssleay32 HINTS "${PROJECT_SOURCE_DIR}/dependency/openssl/out32dll" "${PROJECT_SOURCE_DIR}/dependency/openssl" "/usr/local/opt/openssl/lib" "/usr/lib" "/usr/local/lib" "/opt/local/lib" ) -+find_library( crypto_LIBRARY_SHARED libcrypto.so libcrypto.dylib libeay32 HINTS "${PROJECT_SOURCE_DIR}/dependency/openssl/out32dll" "${PROJECT_SOURCE_DIR}/dependency/openssl" "/usr/local/opt/openssl/lib" "/usr/lib" "/usr/local/lib" "/opt/local/lib" ) - - find_path( ssl_INCLUDE openssl/ssl.h HINTS "${PROJECT_SOURCE_DIR}/dependency/openssl/inc32" "${PROJECT_SOURCE_DIR}/dependency/openssl/include" "/usr/local/opt/openssl/include" "/usr/include" "/usr/local/include" "/opt/local/include" ) - --- -2.19.0.windows.1 - diff --git a/contrib/src/restinio/SHA512SUMS b/contrib/src/restinio/SHA512SUMS new file mode 100644 index 0000000000000000000000000000000000000000..d582da917b2b64b169f8ab0e497d37963aa3633c --- /dev/null +++ b/contrib/src/restinio/SHA512SUMS @@ -0,0 +1 @@ +3713ec6fce780974c1b833411282e878c00dff3ae1b8a252884a9e970b12dc67899cd7642632a97ec9715a928232953cbb26f128e9e603b043faa9774559f8a2 restinio-v.0.5.1.2.tar.gz diff --git a/contrib/src/restinio/fetch_and_patch.bat b/contrib/src/restinio/fetch_and_patch.bat new file mode 100644 index 0000000000000000000000000000000000000000..60a8348c17b5b4240666bc0cc8d723f3cc821f71 --- /dev/null +++ b/contrib/src/restinio/fetch_and_patch.bat @@ -0,0 +1,20 @@ +set BUILD=%SRC%..\build + +RESTINIO_VERSION=v.0.5.1 +RESTINIO_URL=https://github.com/Stiffstream/restinio/archive/%RESTINIO_VERSION%.tar.gz + +mkdir %BUILD% + +if %USE_CACHE%==1 ( + copy %CACHE_DIR%\%RESTINIO_VERSION%.tar.gz %cd% +) else ( + %WGET_CMD% %RESTINIO_URL% +) + +7z -y x %RESTINIO_VERSION%.tar.gz && 7z -y x %RESTINIO_VERSION%.tar -o%BUILD% +del %RESTINIO_VERSION%.tar && del %RESTINIO_VERSION%.tar.gz && del %BUILD%\pax_global_header +rename %BUILD%\restinio-%RESTINIO_VERSION% restinio + +cd %BUILD%\restinio + +cd %SRC% diff --git a/contrib/src/restinio/rules.mak b/contrib/src/restinio/rules.mak new file mode 100644 index 0000000000000000000000000000000000000000..87846d8a35cf403ccdce389b2d3894b9e7aa6ebc --- /dev/null +++ b/contrib/src/restinio/rules.mak @@ -0,0 +1,42 @@ +# RESTINIO +RESTINIO_VERSION := v.0.5.1.2 +RESTINIO_URL := https://github.com/Stiffstream/restinio/archive/$(RESTINIO_VERSION).tar.gz + +PKGS += restinio +ifeq ($(call need_pkg,'restinio'),) +PKGS_FOUND += restinio +endif + +# Avoid building distro-provided dependencies in case RESTinio was built manually +ifneq ($(call need_pkg,"zlib"),) +DEPS_restinio += zlib +endif +ifneq ($(call need_pkg,"asio"),) +DEPS_restinio += asio +endif +ifneq ($(call need_pkg,"fmt >= 5.3.0"),) +DEPS_restinio += fmt +endif +ifneq ($(call need_pkg,"http_parser >= 2.9.3"),) +DEPS_restinio += http_parser +endif + +RESTINIO_CMAKECONF = -DRESTINIO_TEST=OFF -DRESTINIO_SAMPLE=OFF -DRESTINIO_INSTALL_SAMPLES=OFF \ + -DRESTINIO_BENCH=OFF -DRESTINIO_INSTALL_BENCHES=OFF -DRESTINIO_FIND_DEPS=ON \ + -DRESTINIO_ALLOW_SOBJECTIZER=OFF -DRESTINIO_USE_BOOST_ASIO=none \ + -DZLIB_LIBRARY="$(PREFIX)/lib" -DZLIB_INCLUDE_DIR="$(PREFIX)/include" + +$(TARBALLS)/restinio-$(RESTINIO_VERSION).tar.gz: + $(call download,$(RESTINIO_URL)) + +.sum-restinio: restinio-$(RESTINIO_VERSION).tar.gz + +restinio: restinio-$(RESTINIO_VERSION).tar.gz + $(UNPACK) + $(UPDATE_AUTOCONFIG) && cd $(UNPACK_DIR) + $(MOVE) + +.restinio: restinio .sum-restinio + cd $</dev && $(HOSTVARS) $(CMAKE) $(RESTINIO_CMAKECONF) . + cd $</dev && $(MAKE) install + touch $@ diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp index 4b69a43d31b999740955c6ac3ce32bad5895f4ea..de6e75dea20174c6a98967660dc5d2b8ffbce263 100644 --- a/src/jamidht/jamiaccount.cpp +++ b/src/jamidht/jamiaccount.cpp @@ -2253,7 +2253,7 @@ JamiAccount::doRegister_() static auto log_warn = [](char const* m, va_list args) { Logger::vlog(LOG_WARNING, nullptr, 0, true, m, args); }; static auto log_debug = [](char const* m, va_list args) { Logger::vlog(LOG_DEBUG, nullptr, 0, true, m, args); }; #ifndef _MSC_VER - context.logger = std::make_unique<dht::Logger>( + context.logger = std::make_shared<dht::Logger>( log_error, (dht_log_level > 1) ? log_warn : silent, (dht_log_level > 2) ? log_debug : silent); @@ -2264,16 +2264,17 @@ JamiAccount::doRegister_() auto now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count(); jami::emitSignal<DRing::DebugSignal::MessageSend>(std::to_string(now) + " " + std::string(tmp)); }; - context.logger = std::make_unique<dht::Logger>(log_all, log_all, silent); + context.logger = std::make_shared<dht::Logger>(log_all, log_all, silent); #else if (dht_log_level > 2) { - context.logger = std::make_unique<dht::Logger>(log_error, log_warn, log_debug); + context.logger = std::make_shared<dht::Logger>(log_error, log_warn, log_debug); } else if (dht_log_level > 1) { - context.logger = std::make_unique<dht::Logger>(log_error, log_warn, silent); + context.logger = std::make_shared<dht::Logger>(log_error, log_warn, silent); } else { - context.logger = std::make_unique<dht::Logger>(log_error, silent, silent); + context.logger = std::make_shared<dht::Logger>(log_error, silent, silent); } #endif + //logger_ = std::make_shared<dht::Logger>(log_error, log_warn, log_debug); } context.certificateStore = [](const dht::InfoHash& pk_id) { std::vector<std::shared_ptr<dht::crypto::Certificate>> ret; diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h index e21208840b153f7e1c32dc4cfa5209b78fb1fe25..cc30163557bb02910746b0b1d13a32750bd77344 100644 --- a/src/jamidht/jamiaccount.h +++ b/src/jamidht/jamiaccount.h @@ -436,6 +436,7 @@ class JamiAccount : public SIPAccountBase { std::string nameServer_; std::string registeredName_; #endif + std::shared_ptr<dht::Logger> logger_; /** * Compute archive encryption key and DHT storage location from password and PIN. diff --git a/src/jamidht/namedirectory.cpp b/src/jamidht/namedirectory.cpp index 04e54076ee270b32a5813491a42a94a0d1de44a8..d3986647a463294ed15c24927956102abe3a61de 100644 --- a/src/jamidht/namedirectory.cpp +++ b/src/jamidht/namedirectory.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2016-2019 Savoir-faire Linux Inc. * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,13 +24,18 @@ #include "fileutils.h" #include "base64.h" #include "scheduled_executor.h" -#include "manager.h" +#include <asio.hpp> + +#include "manager.h" #include <opendht/thread_pool.h> #include <opendht/crypto.h> +#include <opendht/utils.h> +#include <opendht/http.h> +#include <opendht/log_enable.h> + #include <msgpack.hpp> #include <json/json.h> -#include <restbed> /* for visual studio */ #include <ciso646> @@ -41,8 +47,11 @@ namespace jami { constexpr const char* const QUERY_NAME {"/name/"}; constexpr const char* const QUERY_ADDR {"/addr/"}; -constexpr const char* const HTTPS_PROTO {"https://"}; constexpr const char* const CACHE_DIRECTORY {"namecache"}; + +constexpr const char* const HTTPS_URI {"https://"}; +static const std::string HTTPS_PROTO {"https"}; + const std::string HEX_PREFIX = "0x"; constexpr std::chrono::seconds SAVE_INTERVAL {5}; @@ -52,21 +61,25 @@ const std::regex NAME_VALIDATOR {"^[a-zA-Z0-9-_]{3,32}$"}; constexpr size_t MAX_RESPONSE_SIZE {1024 * 1024}; -void toLower(std::string& string) +using Request = dht::http::Request; + +void +toLower(std::string& string) { std::transform(string.begin(), string.end(), string.begin(), ::tolower); } void -NameDirectory::lookupUri(const std::string& uri, const std::string& default_server, LookupCallback cb) +NameDirectory::lookupUri(const std::string& uri, const std::string& default_server, + LookupCallback cb) { std::smatch pieces_match; if (std::regex_match(uri, pieces_match, URI_VALIDATOR)) { if (pieces_match.size() == 4) { if (pieces_match[2].length() == 0) - instance(default_server).lookupName(pieces_match[3], cb); + instance(default_server).lookupName(pieces_match[3], std::move(cb)); else - instance(pieces_match[3].str()).lookupName(pieces_match[2], cb); + instance(pieces_match[3].str()).lookupName(pieces_match[2], std::move(cb)); return; } } @@ -74,10 +87,12 @@ NameDirectory::lookupUri(const std::string& uri, const std::string& default_serv cb("", Response::invalidResponse); } -NameDirectory::NameDirectory(const std::string& s) - : serverHost_(s), - cachePath_(fileutils::get_cache_dir()+DIR_SEPARATOR_STR+CACHE_DIRECTORY+DIR_SEPARATOR_STR+serverHost_), - executor_(std::make_shared<dht::Executor>(dht::ThreadPool::io(), 8)) +NameDirectory::NameDirectory(const std::string& s, std::shared_ptr<dht::Logger> l) + : serverHost_(s) + , cachePath_(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + CACHE_DIRECTORY + DIR_SEPARATOR_STR + serverHost_) + , logger_(l) + , httpContext_(Manager::instance().ioContext()) + , resolver_(std::make_shared<dht::http::Resolver>(*httpContext_, serverHost_, HTTPS_PROTO, true, logger_)) {} void @@ -86,7 +101,8 @@ NameDirectory::load() loadCache(); } -NameDirectory& NameDirectory::instance(const std::string& server) +NameDirectory& +NameDirectory::instance(const std::string& server, std::shared_ptr<dht::Logger> l) { const std::string& s = server.empty() ? DEFAULT_SERVER_HOST : server; static std::mutex instanceMtx {}; @@ -95,96 +111,99 @@ NameDirectory& NameDirectory::instance(const std::string& server) static std::map<std::string, NameDirectory> instances {}; auto r = instances.emplace(std::piecewise_construct, std::forward_as_tuple(s), - std::forward_as_tuple(s)); + std::forward_as_tuple(s, l)); if (r.second) r.first->second.load(); return r.first->second; } -size_t getContentLength(restbed::Response& reply) -{ - size_t length = 0; -#ifdef RESTBED_OLD_API - reply.get_header("Content-Length", length); -#else - length = reply.get_header("Content-Length", 0); -#endif - return length; +void +NameDirectory::setHeaderFields(Request& request){ + const std::string host = HTTPS_PROTO + ":" + serverHost_; + request.set_header_field(restinio::http_field_t::host, host); + request.set_header_field(restinio::http_field_t::user_agent, "JamiDHT"); + request.set_header_field(restinio::http_field_t::accept, "*/*"); + request.set_header_field(restinio::http_field_t::content_type, "application/json"); } -void NameDirectory::lookupAddress(const std::string& addr, LookupCallback cb) +void +NameDirectory::lookupAddress(const std::string& addr, LookupCallback cb) { std::string cacheResult = nameCache(addr); if (not cacheResult.empty()) { cb(cacheResult, Response::found); return; } - - restbed::Uri uri(HTTPS_PROTO + serverHost_ + QUERY_ADDR + addr); - auto req = std::make_shared<restbed::Request>(uri); - req->set_header("Accept", "*/*"); - req->set_header("Host", serverHost_); - - JAMI_DBG("Address lookup for %s: %s", addr.c_str(), uri.to_string().c_str()); - - executor_->run([this, req, cb=std::move(cb), addr] { - try { - restbed::Http::async(req, [this, cb=std::move(cb), addr=std::move(addr)] - (const std::shared_ptr<restbed::Request>&, - const std::shared_ptr<restbed::Response>& reply) - { - auto code = reply->get_status_code(); - if (code == 200) { - size_t length = getContentLength(*reply); - if (length > MAX_RESPONSE_SIZE) { - cb("", Response::error); - return; - } - restbed::Http::fetch(length, reply); - std::string body; - reply->get_body(body); - - Json::Value json; - Json::CharReaderBuilder rbuilder; - auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader()); - if (!reader->parse(&body[0], &body[body.size()], &json, nullptr)) { - JAMI_ERR("Address lookup for %s: can't parse server response: %s", addr.c_str(), body.c_str()); - cb("", Response::error); - return; - } - auto name = json["name"].asString(); - if (not name.empty()) { - JAMI_DBG("Found name for %s: %s", addr.c_str(), name.c_str()); - { - std::lock_guard<std::mutex> l(lock_); - addrCache_.emplace(name, addr); - nameCache_.emplace(addr, name); - } - cb(name, Response::found); - scheduleSave(); - } else { - cb("", Response::notFound); - } - } else if (code >= 400 && code < 500) { - cb("", Response::notFound); - } else { + auto request = std::make_shared<Request>(*httpContext_, resolver_, logger_); + auto reqid = request->id(); + try { + request->set_connection_type(restinio::http_connection_header_t::keep_alive); + request->set_target(QUERY_ADDR + addr); + request->set_method(restinio::http_method_get()); + setHeaderFields(*request); + + const std::string uri = HTTPS_URI + serverHost_ + QUERY_ADDR + addr; + JAMI_DBG("Address lookup for %s: %s", addr.c_str(), uri.c_str()); + request->add_on_state_change_callback([this, cb=std::move(cb), reqid, addr] + (Request::State state, const dht::http::Response& response){ + if (state != Request::State::DONE) + return; + if (response.status_code >= 400 && response.status_code < 500){ + cb("", Response::notFound); + } + else if (response.status_code != 200){ + JAMI_ERR("Adress lookup for %s failed with code=%i", addr.c_str(), response.status_code); + cb("", Response::error); + } + try { + Json::Value json; + std::string err; + Json::CharReaderBuilder rbuilder; + auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader()); + if (!reader->parse(response.body.data(), response.body.data() + response.body.size(), &json, &err)){ + JAMI_DBG("Address lookup for %s: can't parse server response: %s", addr.c_str(), response.body.c_str()); cb("", Response::error); + return; } - }); - } catch (const std::exception& e) { - JAMI_ERR("Error when performing address lookup: %s", e.what()); - cb("", Response::error); - } - }); + auto name = json["name"].asString(); + if (name.empty()){ + cb(name, Response::notFound); + return; + } + JAMI_DBG("Found name for %s: %s", addr.c_str(), name.c_str()); + { + std::lock_guard<std::mutex> l(cacheLock_); + addrCache_.emplace(name, addr); + nameCache_.emplace(addr, name); + } + cb(name, Response::found); + scheduleCacheSave(); + } + catch (const std::exception& e) { + JAMI_ERR("Error when performing address lookup: %s", e.what()); + cb("", Response::error); + } + requests_.erase(reqid); + }); + request->send(); + requests_[reqid] = request; + } + catch (const std::exception &e){ + JAMI_ERR("Error when performing address lookup: %s", e.what()); + requests_.erase(reqid); + } } bool -NameDirectory::verify(const std::string& name, const dht::crypto::PublicKey& pk, const std::string& signature) +NameDirectory::verify(const std::string& name, const dht::crypto::PublicKey& pk, + const std::string& signature) { - return pk.checkSignature(std::vector<uint8_t>(name.begin(), name.end()), base64::decode(signature)); + return pk.checkSignature(std::vector<uint8_t>(name.begin(), name.end()), + base64::decode(signature)); } -void NameDirectory::lookupName(const std::string& n, LookupCallback cb) +void +NameDirectory::lookupName(const std::string& n, LookupCallback cb) { std::string name {n}; if (not validateName(name)) { @@ -192,44 +211,39 @@ void NameDirectory::lookupName(const std::string& n, LookupCallback cb) return; } toLower(name); - std::string cacheResult = addrCache(name); if (not cacheResult.empty()) { cb(cacheResult, Response::found); return; } - - restbed::Uri uri(HTTPS_PROTO + serverHost_ + QUERY_NAME + name); - JAMI_DBG("Name lookup for %s: %s", name.c_str(), uri.to_string().c_str()); - - auto request = std::make_shared<restbed::Request>(std::move(uri)); - request->set_header("Accept", "*/*"); - request->set_header("Host", serverHost_); - - executor_->run([this, request, cb=std::move(cb), name]{ - try { - restbed::Http::async(request, [this, cb=std::move(cb), name=std::move(name)] - (const std::shared_ptr<restbed::Request>&, - const std::shared_ptr<restbed::Response>& reply) - { - auto code = reply->get_status_code(); - if (code != 200) - JAMI_DBG("Name lookup for %s: got reply code %d", name.c_str(), code); - if (code >= 200 && code < 300) { - size_t length = getContentLength(*reply); - if (length > MAX_RESPONSE_SIZE) { - cb("", Response::error); - return; - } - restbed::Http::fetch(length, reply); - std::string body; - reply->get_body(body); - + auto request = std::make_shared<Request>(*httpContext_, resolver_, logger_); + auto reqid = request->id(); + try { + request->set_connection_type(restinio::http_connection_header_t::keep_alive); + request->set_target(QUERY_NAME + name); + request->set_method(restinio::http_method_get()); + setHeaderFields(*request); + + const std::string uri = HTTPS_URI + serverHost_ + QUERY_NAME + name; + JAMI_DBG("Name lookup for %s: %s", name.c_str(), uri.c_str()); + + request->add_on_state_change_callback([this, reqid, name, cb=std::move(cb)] + (Request::State state, const dht::http::Response& response){ + if (state != Request::State::DONE) + return; + if (response.status_code >= 400 && response.status_code < 500) + cb("", Response::notFound); + else if (response.status_code < 200 || response.status_code > 299) + cb("", Response::error); + else { + try { Json::Value json; + std::string err; Json::CharReaderBuilder rbuilder; auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader()); - if (!reader->parse(&body[0], &body[body.size()], &json, nullptr)) { - JAMI_ERR("Name lookup for %s: can't parse server response: %s", name.c_str(), body.c_str()); + if (!reader->parse(response.body.data(), response.body.data() + response.body.size(), &json, &err)){ + JAMI_ERR("Name lookup for %s: can't parse server response: %s", + name.c_str(), response.body.c_str()); cb("", Response::error); return; } @@ -243,11 +257,12 @@ void NameDirectory::lookupName(const std::string& n, LookupCallback cb) cb("", Response::notFound); return; } - - if (not publickey.empty() and not signature.empty()) { + if (not publickey.empty() and not signature.empty()){ try { auto pk = dht::crypto::PublicKey(base64::decode(publickey)); - if(pk.getId().toString() != addr or not verify(name, pk, signature)) { + if (pk.getId().toString() != addr or + not verify(name, pk, signature)) + { cb("", Response::invalidResponse); return; } @@ -256,34 +271,41 @@ void NameDirectory::lookupName(const std::string& n, LookupCallback cb) return; } } - JAMI_DBG("Found address for %s: %s", name.c_str(), addr.c_str()); { - std::lock_guard<std::mutex> l(lock_); + std::lock_guard<std::mutex> l(cacheLock_); addrCache_.emplace(name, addr); nameCache_.emplace(addr, name); } cb(addr, Response::found); - scheduleSave(); - } else if (code >= 400 && code < 500) { - cb("", Response::notFound); - } else { + scheduleCacheSave(); + } + catch (const std::exception& e) { + JAMI_ERR("Error when performing name lookup: %s", e.what()); cb("", Response::error); } - }); - } catch (const std::exception& e) { - JAMI_ERR("Error when performing name lookup: %s", e.what()); - cb("", Response::error); - } - }); + } + requests_.erase(reqid); + }); + request->send(); + requests_[reqid] = request; + } + catch (const std::exception &e){ + JAMI_ERR("Name lookup for %s failed: %s", name.c_str(), e.what()); + requests_.erase(reqid); + } } -bool NameDirectory::validateName(const std::string& name) const +bool +NameDirectory::validateName(const std::string& name) const { return std::regex_match(name, NAME_VALIDATOR); } + using Blob = std::vector<uint8_t>; -void NameDirectory::registerName(const std::string& addr, const std::string& n, const std::string& owner, RegistrationCallback cb, const std::string& signedname, const std::string& publickey) +void NameDirectory::registerName(const std::string& addr, const std::string& n, + const std::string& owner, RegistrationCallback cb, + const std::string& signedname, const std::string& publickey) { std::string name {n}; if (not validateName(name)) { @@ -299,91 +321,84 @@ void NameDirectory::registerName(const std::string& addr, const std::string& n, cb(RegistrationResponse::alreadyTaken); return; } - - auto request = std::make_shared<restbed::Request>(restbed::Uri(HTTPS_PROTO + serverHost_ + QUERY_NAME + name)); - request->set_header("Accept", "*/*"); - request->set_header("Host", serverHost_); - request->set_header("Content-Type", "application/json"); - request->set_method("POST"); std::string body; { std::stringstream ss; ss << "{\"addr\":\"" << addr << "\",\"owner\":\"" << owner << - "\",\"signature\":\"" << signedname << "\",\"publickey\":\"" << base64::encode(jami::Blob(publickey.begin(), publickey.end())) << "\"}"; - + "\",\"signature\":\"" << signedname << + "\",\"publickey\":\"" << base64::encode( + jami::Blob(publickey.begin(), publickey.end())) << "\"}"; body = ss.str(); } - request->set_body(body); - request->set_header("Content-Length", std::to_string(body.size())); - - auto params = std::make_shared<restbed::Settings>(); - params->set_connection_timeout(std::chrono::seconds(120)); - - JAMI_WARN("registerName: sending request %s %s", addr.c_str(), name.c_str()); - - executor_->run([this, request, params, cb=std::move(cb), addr, name]{ - try { - restbed::Http::async(request, [this, cb=std::move(cb), name=std::move(name), addr=std::move(addr)] - (const std::shared_ptr<restbed::Request>&, - const std::shared_ptr<restbed::Response>& reply) - { - auto code = reply->get_status_code(); - JAMI_DBG("Got reply for registration of %s -> %s: code %d", name.c_str(), addr.c_str(), code); - if (code >= 200 && code < 300) { - size_t length = getContentLength(*reply); - if (length > MAX_RESPONSE_SIZE) { - cb(RegistrationResponse::error); - return; - } - restbed::Http::fetch(length, reply); - std::string body; - reply->get_body(body); - - Json::Value json; - Json::CharReaderBuilder rbuilder; - auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader()); - if (!reader->parse(&body[0], &body[body.size()], &json, nullptr)) { - cb(RegistrationResponse::error); - return; - } - auto success = json["success"].asBool(); - JAMI_DBG("Got reply for registration of %s -> %s: %s", name.c_str(), addr.c_str(), success ? "success" : "failure"); - if (success) { - std::lock_guard<std::mutex> l(lock_); - addrCache_.emplace(name, addr); - nameCache_.emplace(addr, name); - } - cb(success ? RegistrationResponse::success : RegistrationResponse::error); - } else if(code == 400){ - cb(RegistrationResponse::incompleteRequest); - JAMI_ERR("RegistrationResponse::incompleteRequest"); - } else if(code == 401){ - cb(RegistrationResponse::signatureVerificationFailed); - JAMI_ERR("RegistrationResponse::signatureVerificationFailed"); - } else if (code == 403) { - cb(RegistrationResponse::alreadyTaken); - JAMI_ERR("RegistrationResponse::alreadyTaken"); - } else if (code == 409) { - cb(RegistrationResponse::alreadyTaken); - JAMI_ERR("RegistrationResponse::alreadyTaken"); - } else if (code > 400 && code < 500) { - cb(RegistrationResponse::alreadyTaken); - JAMI_ERR("RegistrationResponse::alreadyTaken"); - } else { + auto request = std::make_shared<Request>(*httpContext_, resolver_, logger_); + auto reqid = request->id(); + try { + request->set_connection_type(restinio::http_connection_header_t::keep_alive); + request->set_target(QUERY_NAME + name); + request->set_method(restinio::http_method_post()); + setHeaderFields(*request); + request->set_body(body); + + JAMI_WARN("RegisterName: sending request %s %s", addr.c_str(), name.c_str()); + + request->add_on_state_change_callback([this, reqid, name, addr, cb=std::move(cb)] + (Request::State state, const dht::http::Response& response){ + if (state != Request::State::DONE) + return; + if (response.status_code == 400){ + cb(RegistrationResponse::incompleteRequest); + JAMI_ERR("RegistrationResponse::incompleteRequest"); + } else if (response.status_code == 401){ + cb(RegistrationResponse::signatureVerificationFailed); + JAMI_ERR("RegistrationResponse::signatureVerificationFailed"); + } else if (response.status_code == 403){ + cb(RegistrationResponse::alreadyTaken); + JAMI_ERR("RegistrationResponse::alreadyTaken"); + } else if (response.status_code == 409){ + cb(RegistrationResponse::alreadyTaken); + JAMI_ERR("RegistrationResponse::alreadyTaken"); + } else if (response.status_code > 400 && response.status_code < 500){ + cb(RegistrationResponse::alreadyTaken); + JAMI_ERR("RegistrationResponse::alreadyTaken"); + } else if (response.status_code < 200 || response.status_code > 299){ + cb(RegistrationResponse::error); + JAMI_ERR("RegistrationResponse::error"); + } else { + Json::Value json; + std::string err; + Json::CharReaderBuilder rbuilder; + + auto reader = std::unique_ptr<Json::CharReader>(rbuilder.newCharReader()); + if (!reader->parse(response.body.data(), response.body.data() + response.body.size(), &json, &err)){ cb(RegistrationResponse::error); - JAMI_ERR("RegistrationResponse::error"); + return; } - }, params); - } catch (const std::exception& e) { - JAMI_ERR("Error when performing name registration: %s", e.what()); - cb(RegistrationResponse::error); - } - }); + auto success = json["success"].asBool(); + JAMI_DBG("Got reply for registration of %s %s: %s", + name.c_str(), addr.c_str(), success ? "success" : "failure"); + if (success){ + std::lock_guard<std::mutex> l(cacheLock_); + addrCache_.emplace(name, addr); + nameCache_.emplace(addr, name); + } + cb(success ? RegistrationResponse::success : RegistrationResponse::error); + } + requests_.erase(reqid); + }); + request->send(); + requests_[reqid] = request; + } + catch (const std::exception &e){ + JAMI_ERR("Error when performing name registration: %s", e.what()); + cb(RegistrationResponse::error); + requests_.erase(reqid); + } } void -NameDirectory::scheduleSave() +NameDirectory::scheduleCacheSave() { + JAMI_DBG("Scheduling cache save to %s", cachePath_.c_str()); std::weak_ptr<Task> task = Manager::instance().scheduler().scheduleIn([this]{ dht::ThreadPool::io().run([this] { saveCache(); @@ -401,10 +416,11 @@ NameDirectory::saveCache() std::lock_guard<std::mutex> lock(fileutils::getFileLock(cachePath_)); std::ofstream file = fileutils::ofstream(cachePath_, std::ios::trunc | std::ios::binary); { - std::lock_guard<std::mutex> l(lock_); + std::lock_guard<std::mutex> l(cacheLock_); msgpack::pack(file, nameCache_); } - JAMI_DBG("Saved %lu name-address mappings to %s", (long unsigned)nameCache_.size(), cachePath_.c_str()); + JAMI_DBG("Saved %lu name-address mappings to %s", + (long unsigned) nameCache_.size(), cachePath_.c_str()); } void @@ -429,13 +445,13 @@ NameDirectory::loadCache() } // load values - std::lock_guard<std::mutex> l(lock_); + std::lock_guard<std::mutex> l(cacheLock_); msgpack::object_handle oh; if (pac.next(oh)) oh.get().convert(nameCache_); for (const auto& m : nameCache_) addrCache_.emplace(m.second, m.first); - JAMI_DBG("Loaded %lu name-address mappings", (long unsigned)nameCache_.size()); + JAMI_DBG("Loaded %lu name-address mappings", (long unsigned) nameCache_.size()); } } diff --git a/src/jamidht/namedirectory.h b/src/jamidht/namedirectory.h index ee2f226a3357455c4f89c4dd4d31853e7f60730b..f3b18f42693e00a9bd5366ed1aa500003e5a9aea 100644 --- a/src/jamidht/namedirectory.h +++ b/src/jamidht/namedirectory.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2016-2019 Savoir-faire Linux Inc. * Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * Vsevolod Ivanov <vsevolod.ivanov@savoirfairelinux.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,17 +20,25 @@ #include "noncopyable.h" +#include <asio/io_context.hpp> + #include <functional> #include <map> #include <string> #include <mutex> #include <memory> +#include <thread> namespace dht { class Executor; namespace crypto { struct PublicKey; } +namespace http { +class Request; +class Resolver; +} +struct Logger; } namespace jami { @@ -52,18 +61,21 @@ public: using RegistrationCallback = std::function<void(RegistrationResponse response)>; NameDirectory() {} - NameDirectory(const std::string& s); + NameDirectory(const std::string& s, std::shared_ptr<dht::Logger> l = {}); void load(); - static NameDirectory& instance(const std::string& server); + static NameDirectory& instance(const std::string& server, std::shared_ptr<dht::Logger> l = {}); static NameDirectory& instance() { return instance(DEFAULT_SERVER_HOST); } - static void lookupUri(const std::string& uri, const std::string& default_server, LookupCallback cb); + static void lookupUri(const std::string& uri, const std::string& default_server, + LookupCallback cb); void lookupAddress(const std::string& addr, LookupCallback cb); void lookupName(const std::string& name, LookupCallback cb); - void registerName(const std::string& addr, const std::string& name, const std::string& owner, RegistrationCallback cb, const std::string& signedname, const std::string& publickey); + void registerName(const std::string& addr, const std::string& name, + const std::string& owner, RegistrationCallback cb, + const std::string& signedname, const std::string& publickey); const std::string& getServer() const { return serverHost_; @@ -74,33 +86,45 @@ private: NameDirectory(NameDirectory&&) = delete; constexpr static const char* const DEFAULT_SERVER_HOST = "ns.jami.net"; - std::mutex lock_ {}; - const std::string serverHost_ {DEFAULT_SERVER_HOST}; const std::string cachePath_; + std::mutex cacheLock_ {}; + std::shared_ptr<dht::Logger> logger_; + + /* + * ASIO I/O Context for sockets in httpClient_. + * Note: Each context is used in one thread only. + */ + std::shared_ptr<asio::io_context> httpContext_; + std::shared_ptr<dht::http::Resolver> resolver_; + std::map<unsigned int /*id*/, std::shared_ptr<dht::http::Request>> requests_; + std::map<std::string, std::string> nameCache_ {}; std::map<std::string, std::string> addrCache_ {}; std::weak_ptr<Task> saveTask_; - std::shared_ptr<dht::Executor> executor_; + + void setHeaderFields(dht::http::Request& request); std::string nameCache(const std::string& addr) { - std::lock_guard<std::mutex> l(lock_); + std::lock_guard<std::mutex> l(cacheLock_); auto cacheRes = nameCache_.find(addr); return cacheRes != nameCache_.end() ? cacheRes->second : std::string{}; } std::string addrCache(const std::string& name) { - std::lock_guard<std::mutex> l(lock_); + std::lock_guard<std::mutex> l(cacheLock_); auto cacheRes = addrCache_.find(name); return cacheRes != addrCache_.end() ? cacheRes->second : std::string{}; } bool validateName(const std::string& name) const; - static bool verify(const std::string& name, const dht::crypto::PublicKey& publickey, const std::string& signature); + static bool verify(const std::string& name, + const dht::crypto::PublicKey& publickey, + const std::string& signature); - void scheduleSave(); + void scheduleCacheSave(); void saveCache(); void loadCache(); }; -} \ No newline at end of file +}