mirror of
https://github.com/Netflix/dial-reference.git
synced 2026-06-08 10:59:59 +00:00
281 lines
8.4 KiB
C++
281 lines
8.4 KiB
C++
/*
|
|
* Copyright (c) 2014 Netflix, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* Redistributions of source code must retain the above copyright notice, this
|
|
* list of conditions and the following disclaimer.
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL NETFLIX OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "DialServer.h"
|
|
#include <curl/curl.h>
|
|
|
|
using namespace std;
|
|
|
|
enum DIAL_COMMAND{
|
|
COMMAND_LAUNCH,
|
|
COMMAND_STATUS,
|
|
COMMAND_KILL,
|
|
COMMAND_HIDE
|
|
};
|
|
const char* DIAL_COMMAND_STR[] = {"LAUNCH", "STATUS", "KILL", "HIDE"};
|
|
|
|
static size_t header_cb(void* ptr, size_t size, size_t nmemb, void* userdata)
|
|
{
|
|
if ((size * nmemb) != 0) {
|
|
string newHeader((char*)ptr);
|
|
string *header = static_cast<string*>(userdata);
|
|
header->append(newHeader);
|
|
ATRACE("%s: Adding header: %s", __FUNCTION__, newHeader.c_str());
|
|
}
|
|
return (size * nmemb);
|
|
}
|
|
|
|
static size_t receiveData(void *ptr, size_t size, size_t nmemb, void *userdata)
|
|
{
|
|
if ((size * nmemb) != 0) {
|
|
string *body= static_cast<string*>(userdata);
|
|
body->append((char*)ptr);
|
|
ATRACE("%s: Adding to Body: %s", __FUNCTION__, (char*)ptr);
|
|
}
|
|
return (size * nmemb);
|
|
}
|
|
|
|
int DialServer::sendCommand(
|
|
string &url,
|
|
int command,
|
|
string &payload,
|
|
string &responseHeaders,
|
|
string &responseBody )
|
|
{
|
|
CURL *curl;
|
|
CURLcode res = CURLE_OK;
|
|
|
|
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
|
|
{
|
|
fprintf(stderr, "curl_global_init() failed\n");
|
|
return 0;
|
|
}
|
|
|
|
if ((curl = curl_easy_init()) == NULL)
|
|
{
|
|
fprintf(stderr, "curl_easy_init() failed\n");
|
|
curl_global_cleanup();
|
|
return 0;
|
|
}
|
|
|
|
if (command == COMMAND_LAUNCH || command == COMMAND_HIDE)
|
|
{
|
|
curl_easy_setopt(curl, CURLOPT_POST, true);
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, payload.size());
|
|
if( payload.size() )
|
|
{
|
|
struct curl_slist *slist=NULL;
|
|
slist = curl_slist_append(slist, "Expect:");
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str());
|
|
}
|
|
#ifdef DEBUG
|
|
else ATRACE("Sending empty POST\n");
|
|
#endif
|
|
}
|
|
else if (command == COMMAND_KILL)
|
|
{
|
|
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
|
}
|
|
ATRACE("Sending %s:%s\n", DIAL_COMMAND_STR[command], url.c_str());
|
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
|
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
|
|
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &responseHeaders);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveData);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody);
|
|
res = curl_easy_perform(curl);
|
|
|
|
curl_easy_cleanup(curl);
|
|
curl_global_cleanup();
|
|
return (res == CURLE_OK);
|
|
}
|
|
|
|
string DialServer::getIpAddress()
|
|
{
|
|
// m_appsUrl=http://192.168.1.103:36269/apps/
|
|
if( m_ipAddr.empty() )
|
|
{
|
|
size_t begin = m_appsUrl.find("//");
|
|
if( begin != m_appsUrl.npos )
|
|
{
|
|
begin += 2; // move to the start of the IP address
|
|
size_t end = m_appsUrl.find(":", begin);
|
|
if( end != m_appsUrl.npos )
|
|
{
|
|
m_ipAddr = m_appsUrl.substr( begin, end-begin );
|
|
ATRACE("IP ADDRESS: %s\n", m_ipAddr.c_str() );
|
|
}
|
|
}
|
|
}
|
|
return m_ipAddr;
|
|
}
|
|
|
|
bool DialServer::getFriendlyName( string& name )
|
|
{
|
|
bool retval = false;
|
|
if( !m_ddxml.empty() )
|
|
{
|
|
string friendlyName = "<friendlyName>";
|
|
size_t pos;
|
|
if( ( pos = m_ddxml.find( friendlyName ) ) != m_ddxml.npos )
|
|
{
|
|
string friendlyNameEnd = "</friendlyName>";
|
|
size_t end = m_ddxml.find( friendlyNameEnd );
|
|
name = m_ddxml.substr( pos + friendlyName.size(),
|
|
(end - (pos + friendlyName.size())) );
|
|
ATRACE("***Friendly name=%s***", name.c_str());
|
|
retval = true;
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
bool DialServer::getUuid( string& uuid )
|
|
{
|
|
bool retval = false;
|
|
if( !m_ddxml.empty() )
|
|
{
|
|
string udn = "<UDN>";
|
|
size_t pos;
|
|
if( ( pos = m_ddxml.find( udn ) ) != m_ddxml.npos )
|
|
{
|
|
string udnEnd = "</UDN>";
|
|
size_t end = m_ddxml.find( udnEnd );
|
|
uuid = m_ddxml.substr( pos + udn.size(),
|
|
(end - (pos + udn.size())) );
|
|
ATRACE("***UUID=%s***", uuid.c_str() );
|
|
retval = true;
|
|
}
|
|
#ifdef DEBUG
|
|
else
|
|
{
|
|
ATRACE("Friendly name not found\n%s\n", m_ddxml.c_str());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
string DialServer::getMacAddress()
|
|
{
|
|
return m_macAddr;
|
|
}
|
|
|
|
int DialServer::getWakeOnLanTimeout()
|
|
{
|
|
return m_wakeUpTimeout;
|
|
}
|
|
|
|
int DialServer::launchApplication(
|
|
string &application,
|
|
string &payload,
|
|
string &responseHeaders,
|
|
string &responseBody )
|
|
{
|
|
ATRACE("%s: Launch %s\n", __FUNCTION__, application.c_str());
|
|
string appUrl = m_appsUrl;
|
|
int status = sendCommand( appUrl.append(application), COMMAND_LAUNCH, payload, responseHeaders, responseBody);
|
|
return status;
|
|
}
|
|
|
|
int DialServer::getStatus(
|
|
string &application,
|
|
string &responseHeaders,
|
|
string &responseBody )
|
|
{
|
|
ATRACE("%s: GetStatus %s\n", __FUNCTION__, application.c_str());
|
|
string emptyPayload;
|
|
string appUrl = m_appsUrl;
|
|
int status = sendCommand( appUrl.append(application), COMMAND_STATUS, emptyPayload, responseHeaders, responseBody );
|
|
|
|
if (!status) return 0;
|
|
ATRACE("Body: %s\n", responseBody.c_str());
|
|
unsigned found = responseBody.find("href=");
|
|
if( found != string::npos )
|
|
{
|
|
// The start of href is after href= and the quote
|
|
unsigned href_start = found + 5 + 1;
|
|
|
|
// get the body from the start of href to the end, then find
|
|
// the last quote delimiter.
|
|
string tmp = responseBody.substr( href_start );
|
|
unsigned href_end = tmp.find("\"");
|
|
m_stopEndPoint = responseBody.substr( href_start, href_end );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int DialServer::stopApplication(
|
|
string &application,
|
|
string &responseHeaders )
|
|
{
|
|
ATRACE("%s: Quit %s\n", __FUNCTION__, application.c_str());
|
|
string emptyPayload, responseBody; // dropping this
|
|
string appUrl = m_appsUrl;
|
|
|
|
// just call status to update the run endpoint
|
|
getStatus( application, responseHeaders, responseBody );
|
|
|
|
int status = sendCommand(
|
|
(appUrl.append(application)).append("/"+m_stopEndPoint),
|
|
COMMAND_KILL, emptyPayload, responseHeaders, responseBody );
|
|
return status;
|
|
}
|
|
|
|
int DialServer::hideApplication(
|
|
string &application,
|
|
string &responseHeaders,
|
|
string &responseBody )
|
|
{
|
|
ATRACE("%s: Hide %s\n", __FUNCTION__, application.c_str());
|
|
string emptyPayload;
|
|
string appUrl = m_appsUrl;
|
|
|
|
// just call status to update the run endpoint
|
|
getStatus( application, responseHeaders, responseBody );
|
|
|
|
int status = sendCommand(
|
|
(appUrl.append(application)).append("/"+m_stopEndPoint).append("/hide"),
|
|
COMMAND_HIDE, emptyPayload, responseHeaders, responseBody );
|
|
return status;
|
|
}
|
|
|
|
int DialServer::getHttpResponseHeader(
|
|
string &responseHeaders,
|
|
string &header,
|
|
string &value )
|
|
{
|
|
return 0;
|
|
}
|