Skip to content
Snippets Groups Projects
Commit b9ccc968 authored by Sébastien Blin's avatar Sébastien Blin Committed by Adrien Béraud
Browse files

proxyserver: add support for UnifiedPush standard

Make the proxy able to support the UnifiedPush platform, so that
applications using the proxy server can use any UnifiedPush provider.

Documentation: https://unifiedpush.org/

How to test:
+ Install a UnifiedPush provider on a device (e.g. https://ntfy.sh)
+ Run dhtnode with a proxyserver and --unifiedpush https://ntfy.sh
+ Subscribe to a random topic on ntfy (e.g. "dhtproxytest")
+ Subscribe to a hash on the DHT:
    curl -X SUBSCRIBE http://my.dht.proxy:8000/key/foo \
         -d '{"key":"dhtproxytest", "platform":"unifiedpush"}'
+ Send data on the subscribed hash

Note: the topic should be completely random.
parent 7e33c4fc
No related branches found
No related tags found
No related merge requests found
...@@ -40,7 +40,8 @@ namespace dht { ...@@ -40,7 +40,8 @@ namespace dht {
enum class PushType { enum class PushType {
None = 0, None = 0,
Android, Android,
iOS iOS,
UnifiedPush
}; };
} }
MSGPACK_ADD_ENUM(dht::PushType) MSGPACK_ADD_ENUM(dht::PushType)
...@@ -65,6 +66,7 @@ struct OPENDHT_PUBLIC ProxyServerConfig { ...@@ -65,6 +66,7 @@ struct OPENDHT_PUBLIC ProxyServerConfig {
std::string address {}; std::string address {};
in_port_t port {8000}; in_port_t port {8000};
std::string pushServer {}; std::string pushServer {};
std::string unifiedPushEndpoint {};
std::string persistStatePath {}; std::string persistStatePath {};
dht::crypto::Identity identity {}; dht::crypto::Identity identity {};
std::string bundleId {}; std::string bundleId {};
...@@ -424,6 +426,7 @@ private: ...@@ -424,6 +426,7 @@ private:
mutable std::atomic<time_point> lastStatsReset_ {time_point::min()}; mutable std::atomic<time_point> lastStatsReset_ {time_point::min()};
std::string pushServer_; std::string pushServer_;
std::string unifiedPushEndpoint_;
std::string bundleId_; std::string bundleId_;
#ifdef OPENDHT_PUSH_NOTIFICATIONS #ifdef OPENDHT_PUSH_NOTIFICATIONS
......
...@@ -212,6 +212,7 @@ DhtProxyServer::DhtProxyServer(const std::shared_ptr<DhtRunner>& dht, ...@@ -212,6 +212,7 @@ DhtProxyServer::DhtProxyServer(const std::shared_ptr<DhtRunner>& dht,
printStatsTimer_(std::make_unique<asio::steady_timer>(*ioContext_, 3s)), printStatsTimer_(std::make_unique<asio::steady_timer>(*ioContext_, 3s)),
connListener_(std::make_shared<ConnectionListener>(std::bind(&DhtProxyServer::onConnectionClosed, this, std::placeholders::_1))), connListener_(std::make_shared<ConnectionListener>(std::bind(&DhtProxyServer::onConnectionClosed, this, std::placeholders::_1))),
pushServer_(config.pushServer), pushServer_(config.pushServer),
unifiedPushEndpoint_(config.unifiedPushEndpoint),
bundleId_(config.bundleId) bundleId_(config.bundleId)
{ {
if (not dht_) if (not dht_)
...@@ -762,6 +763,8 @@ DhtProxyServer::getTypeFromString(const std::string& type) { ...@@ -762,6 +763,8 @@ DhtProxyServer::getTypeFromString(const std::string& type) {
return PushType::Android; return PushType::Android;
else if (type == "ios") else if (type == "ios")
return PushType::iOS; return PushType::iOS;
else if (type == "unifiedpush")
return PushType::UnifiedPush;
return PushType::None; return PushType::None;
} }
...@@ -1012,21 +1015,29 @@ DhtProxyServer::handleCancelPushListen(const asio::error_code &ec, const std::st ...@@ -1012,21 +1015,29 @@ DhtProxyServer::handleCancelPushListen(const asio::error_code &ec, const std::st
void void
DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& json, PushType type, bool highPriority, const std::string& topic) DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& json, PushType type, bool highPriority, const std::string& topic)
{ {
if (pushServer_.empty()) if (pushServer_.empty() and unifiedPushEndpoint_.empty())
return; return;
unsigned reqid = 0; unsigned reqid = 0;
try { try {
auto request = std::make_shared<http::Request>(io_context(), pushHostPort_.first, pushHostPort_.second, auto request = type == PushType::UnifiedPush
pushHostPort_.first.find("https://") == 0, logger_); ? std::make_shared<http::Request>(io_context(), unifiedPushEndpoint_, logger_)
: std::make_shared<http::Request>(io_context(), pushHostPort_.first, pushHostPort_.second, pushHostPort_.first.find("https://") == 0, logger_);
reqid = request->id(); reqid = request->id();
request->set_target("/api/push"); request->set_target(type == PushType::UnifiedPush ? ("/" + token) : "/api/push");
request->set_method(restinio::http_method_post()); request->set_method(restinio::http_method_post());
request->set_header_field(restinio::http_field_t::host, pushServer_.c_str()); request->set_header_field(restinio::http_field_t::host, type == PushType::UnifiedPush ? unifiedPushEndpoint_.c_str() : pushServer_.c_str());
request->set_header_field(restinio::http_field_t::user_agent, "RESTinio client"); request->set_header_field(restinio::http_field_t::user_agent, "RESTinio client");
request->set_header_field(restinio::http_field_t::accept, "*/*"); request->set_header_field(restinio::http_field_t::accept, "*/*");
request->set_header_field(restinio::http_field_t::content_type, "application/json"); request->set_header_field(restinio::http_field_t::content_type, "application/json");
if (type == PushType::UnifiedPush) {
Json::Value notification(Json::objectValue);
notification["message"] = Json::writeString(jsonBuilder_, std::move(json));
notification["topic"] = token;
notification["priority"] = highPriority ? 5 : 1;
request->set_body(Json::writeString(jsonBuilder_, std::move(json)));
} else {
// NOTE: see https://github.com/appleboy/gorush // NOTE: see https://github.com/appleboy/gorush
Json::Value notification(Json::objectValue); Json::Value notification(Json::objectValue);
Json::Value tokens(Json::arrayValue); Json::Value tokens(Json::arrayValue);
...@@ -1061,6 +1072,8 @@ DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& jso ...@@ -1061,6 +1072,8 @@ DhtProxyServer::sendPushNotification(const std::string& token, Json::Value&& jso
Json::Value content; Json::Value content;
content["notifications"] = std::move(notifications); content["notifications"] = std::move(notifications);
request->set_body(Json::writeString(jsonBuilder_, content)); request->set_body(Json::writeString(jsonBuilder_, content));
}
request->add_on_state_change_callback([this, reqid] request->add_on_state_change_callback([this, reqid]
(http::Request::State state, const http::Response& response){ (http::Request::State state, const http::Response& response){
if (state == http::Request::State::DONE){ if (state == http::Request::State::DONE){
......
...@@ -43,7 +43,7 @@ void print_version() { ...@@ -43,7 +43,7 @@ void print_version() {
} }
void print_usage() { void print_usage() {
std::cout << "Usage: dhtnode [-v [-l logfile]] [-i] [-d] [-n network_id] [-p local_port] [-b bootstrap_host[:port]] [--proxyserver local_port] [--proxyserverssl local_port] [--bundleid bundleid]" << std::endl << std::endl; std::cout << "Usage: dhtnode [-v [-l logfile]] [-i] [-d] [-n network_id] [-p local_port] [-b bootstrap_host[:port]] [--proxyserver local_port] [--proxyserverssl local_port] [--bundleid bundleid] [--openpush endpoint]" << std::endl << std::endl;
print_info(); print_info();
} }
...@@ -552,6 +552,7 @@ main(int argc, char **argv) ...@@ -552,6 +552,7 @@ main(int argc, char **argv)
serverConfig.pushServer = params.pushserver; serverConfig.pushServer = params.pushserver;
serverConfig.bundleId = params.bundle_id; serverConfig.bundleId = params.bundle_id;
serverConfig.address = params.proxy_address; serverConfig.address = params.proxy_address;
serverConfig.unifiedPushEndpoint = params.unifiedPushEndpoint;
if (params.proxyserverssl and params.proxy_id.first and params.proxy_id.second){ if (params.proxyserverssl and params.proxy_id.first and params.proxy_id.second){
serverConfig.identity = params.proxy_id; serverConfig.identity = params.proxy_id;
serverConfig.port = params.proxyserverssl; serverConfig.port = params.proxyserverssl;
......
...@@ -130,6 +130,7 @@ struct dht_params { ...@@ -130,6 +130,7 @@ struct dht_params {
in_port_t port {0}; in_port_t port {0};
in_port_t proxyserver {0}; in_port_t proxyserver {0};
in_port_t proxyserverssl {0}; in_port_t proxyserverssl {0};
std::string unifiedPushEndpoint {};
std::string proxyclient {}; std::string proxyclient {};
std::string proxy_address {}; std::string proxy_address {};
std::string pushserver {}; std::string pushserver {};
...@@ -225,6 +226,7 @@ static const constexpr struct option long_options[] = { ...@@ -225,6 +226,7 @@ static const constexpr struct option long_options[] = {
{"syslog", no_argument , nullptr, 'L'}, {"syslog", no_argument , nullptr, 'L'},
{"proxyserver", required_argument, nullptr, 'S'}, {"proxyserver", required_argument, nullptr, 'S'},
{"proxyserverssl", required_argument, nullptr, 'e'}, {"proxyserverssl", required_argument, nullptr, 'e'},
{"unifiedpush", required_argument, nullptr, 'O'},
{"proxy-addr", required_argument, nullptr, 'a'}, {"proxy-addr", required_argument, nullptr, 'a'},
{"proxy-certificate", required_argument, nullptr, 'w'}, {"proxy-certificate", required_argument, nullptr, 'w'},
{"proxy-privkey", required_argument, nullptr, 'K'}, {"proxy-privkey", required_argument, nullptr, 'K'},
...@@ -243,7 +245,7 @@ parseArgs(int argc, char **argv) { ...@@ -243,7 +245,7 @@ parseArgs(int argc, char **argv) {
int opt; int opt;
std::string privkey; std::string privkey;
std::string proxy_privkey; std::string proxy_privkey;
while ((opt = getopt_long(argc, argv, "hidsvDUPp:n:b:f:l:", long_options, nullptr)) != -1) { while ((opt = getopt_long(argc, argv, "hidsvODUPp:n:b:f:l:", long_options, nullptr)) != -1) {
switch (opt) { switch (opt) {
case 'p': { case 'p': {
int port_arg = atoi(optarg); int port_arg = atoi(optarg);
...@@ -261,6 +263,9 @@ parseArgs(int argc, char **argv) { ...@@ -261,6 +263,9 @@ parseArgs(int argc, char **argv) {
std::cout << "Invalid port: " << port_arg << std::endl; std::cout << "Invalid port: " << port_arg << std::endl;
} }
break; break;
case 'O':
params.unifiedPushEndpoint = optarg;
break;
case 'e': { case 'e': {
int port_arg = atoi(optarg); int port_arg = atoi(optarg);
if (port_arg >= 0 && port_arg < 0x10000) if (port_arg >= 0 && port_arg < 0x10000)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment