This commit is contained in:
2025-11-24 14:19:51 +05:30
commit f5c1412b28
6734 changed files with 1527575 additions and 0 deletions

View File

@ -0,0 +1,279 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2016-2020, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
#include "Rackspace2.h"
#include "slikenet/TCPInterface.h"
#include "slikenet/HTTPConnection2.h"
#include "slikenet/linux_adapter.h"
#include "slikenet/osx_adapter.h"
using namespace SLNet;
Rackspace2::Rackspace2()
{
X_Auth_Token[0]=0;
eventCallback=0;
tcp=0;
cloudAccountNumber=0;
reexecuteLastRequestOnAuth=false;
}
Rackspace2::~Rackspace2()
{
}
void Rackspace2::Update(void)
{
RakString stringTransmitted;
RakString hostTransmitted;
RakString responseReceived;
Packet *packet;
SystemAddress sa;
// This is kind of crappy, but for TCP plugins, always do HasCompletedConnectionAttempt, then Receive(), then HasFailedConnectionAttempt(),HasLostConnection()
sa = tcp->HasCompletedConnectionAttempt();
if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
{
//printf("Rackspace2 TCP: Connected to %s\n", sa.ToString());
// serverAddress = sa;
}
for (packet = tcp->Receive(); packet; tcp->DeallocatePacket(packet), packet = tcp->Receive())
;
sa = tcp->HasFailedConnectionAttempt();
//if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
// printf("Rackspace2 TCP: Failed connection attempt to %s\n", sa.ToString());
sa = tcp->HasLostConnection();
if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
{
//printf("Rackspace2 TCP: Lost connection to %s\n", sa.ToString());
// serverAddress=UNASSIGNED_SYSTEM_ADDRESS;
}
SystemAddress hostReceived;
ptrdiff_t contentOffset;
if (httpConnection2->GetResponse(stringTransmitted, hostTransmitted, responseReceived, hostReceived, contentOffset))
{
if (responseReceived.IsEmpty()==false)
{
static FILE *fp = nullptr;
if (fp == nullptr)
fopen_s(&fp, "responses.txt", "wt");
// #low - add nullptr-check (incl. error logging) for fp
fprintf(fp, responseReceived.C_String());
fprintf(fp, "\n");
if (contentOffset==-1)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_NO_CONTENT, responseReceived, contentOffset);
}
else
{
json_error_t error;
json_t *root = json_loads(strstr(responseReceived.C_String() + contentOffset, "{"), JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK, &error);
if (!root)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_BAD_JSON, responseReceived, contentOffset);
}
else
{
void *iter = json_object_iter(root);
const char *firstKey = json_object_iter_key(iter);
if (_stricmp(firstKey, "unauthorized")==0)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_UNAUTHORIZED, responseReceived, contentOffset);
}
else if (_stricmp(firstKey, "itemNotFound")==0)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_404_NOT_FOUND, responseReceived, contentOffset);
}
else if (_stricmp(firstKey, "access")==0)
{
json_t *valAuthToken = json_object_get(json_object_get(json_object_get(root, "access"), "token"), "id");
strcpy_s(X_Auth_Token, json_string_value(valAuthToken));
json_t *valAccountNumber = json_object_get(json_object_get(json_object_get(json_object_get(root, "access"), "token"), "tenant"), "id");
cloudAccountNumber = atoi(json_string_value(valAccountNumber));
if (reexecuteLastRequestOnAuth)
{
reexecuteLastRequestOnAuth=false;
json_t *root2 = json_loads(__addOpLast_dataAsStr.C_String(), 0, &error);
AddOperation(__addOpLast_URL, __addOpLast_isPost, root2, true);
}
else
{
if (eventCallback)
eventCallback->OnResponse(R2RC_AUTHENTICATED, responseReceived, contentOffset);
}
}
else if (_stricmp(firstKey, "domains")==0)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_GOT_DOMAINS, responseReceived, contentOffset);
}
else if (_stricmp(firstKey, "records")==0)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_GOT_RECORDS, responseReceived, contentOffset);
}
else if (_stricmp(firstKey, "servers")==0)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_GOT_SERVERS, responseReceived, contentOffset);
}
else if (_stricmp(firstKey, "images")==0)
{
if (eventCallback)
eventCallback->OnResponse(R2RC_GOT_IMAGES, responseReceived, contentOffset);
}
else if (_stricmp(firstKey, "message")==0)
{
const char *message = json_string_value(json_object_iter_value(iter));
if (strcmp(message, "Invalid authentication token. Please renew.")==0)
{
// Sets reexecuteLastRequestOnAuth to true
// After authenticate completes, will rerun the last run command
Reauthenticate();
}
else
{
if (eventCallback)
eventCallback->OnMessage(message, responseReceived, stringTransmitted, contentOffset);
}
}
else
{
if (eventCallback)
eventCallback->OnResponse(R2RC_UNKNOWN, responseReceived, contentOffset);
}
}
json_decref(root);
}
}
else
{
if (eventCallback)
eventCallback->OnEmptyResponse(stringTransmitted);
}
}
}
void Rackspace2::SetEventCallback(Rackspace2EventCallback *callback)
{
eventCallback=callback;
}
int Rackspace2::GetCloudAccountNumber(void) const
{
return cloudAccountNumber;
}
const char *Rackspace2::GetAuthToken(void) const
{
return (const char*) &X_Auth_Token;
}
void Rackspace2::Reauthenticate(void)
{
reexecuteLastRequestOnAuth=true;
AuthenticateInt(lastAuthenticationURL.C_String(), lastRackspaceCloudUsername.C_String(), lastApiAccessKey.C_String());
}
void Rackspace2::AuthenticateInt(const char *authenticationURL, const char *rackspaceCloudUsername, const char *apiAccessKey)
{
json_t *json_credentials = json_object();
json_object_set(json_credentials, "username", json_string(rackspaceCloudUsername));
json_object_set(json_credentials, "apiKey", json_string(apiAccessKey));
json_t *json_auth = json_object();
json_object_set(json_auth, "RAX-KSKEY:apiKeyCredentials", json_credentials);
json_t *json_root = json_object();
json_object_set(json_root, "auth", json_auth);
RakString URL = authenticationURL;
RakString command = "/tokens";
URL += command;
AddOperation(URL, OT_POST, json_root, false);
}
void Rackspace2::Authenticate(const char *authenticationURL, const char *rackspaceCloudUsername, const char *apiAccessKey)
{
lastAuthenticationURL=authenticationURL;
lastRackspaceCloudUsername=rackspaceCloudUsername;
lastApiAccessKey=apiAccessKey;
AuthenticateInt(authenticationURL, rackspaceCloudUsername,apiAccessKey);
}
void Rackspace2::AddOperation(SLNet::RakString URL, OpType opType, json_t *data, bool setAuthToken)
{
if (tcp==0)
{
tcp = SLNet::OP_NEW<TCPInterface>(_FILE_AND_LINE_);
if (tcp->Start(0, 0, 8)==false)
{
if (eventCallback)
eventCallback->OnTCPFailure();
}
httpConnection2 = SLNet::OP_NEW<HTTPConnection2>(_FILE_AND_LINE_);
tcp->AttachPlugin(httpConnection2);
}
RakString authURLHeader, authURLDomain, authURLPath;
URL.SplitURI(authURLHeader,authURLDomain,authURLPath);
char *jsonStr = "";
if (data)
jsonStr = json_dumps(data, 0);
RakString requestStr;
RakString extraBody;
if (setAuthToken)
{
RakAssert(X_Auth_Token[0]);
// Test expired token
//strcpy_s(X_Auth_Token, "fd6ad67c-fbd3-4b35-94e2-059b6090998e");
extraBody.Set("Accept: application/json\r\nX-Auth-Token: %s", X_Auth_Token);
__addOpLast_URL = URL;
__addOpLast_isPost = opType;
__addOpLast_dataAsStr = jsonStr;
}
else
{
extraBody = "Accept: application/json";
}
if (opType==OT_POST)
requestStr = RakString::FormatForPOST(URL, "application/json", jsonStr, extraBody);
else if (opType==OT_GET)
requestStr = RakString::FormatForGET(URL, extraBody);
else if (opType==OT_DELETE)
requestStr = RakString::FormatForDELETE(URL, extraBody);
else
requestStr = RakString::FormatForPUT(URL, "application/json", jsonStr, extraBody);
bool b = httpConnection2->TransmitRequest(requestStr,authURLDomain, 443, true);
if (!b)
{
if (eventCallback)
eventCallback->OnTransmissionFailed(httpConnection2, requestStr, authURLDomain);
}
if (data)
{
free(jsonStr);
json_decref(data);
}
}

View File

@ -0,0 +1,138 @@
/*
* Original work: Copyright (c) 2014, Oculus VR, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
*
*
* Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
*
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
* license found in the license.txt file in the root directory of this source tree.
*/
/// \file Rackspace.h
/// \brief Helper to class to manage Rackspace servers
#include "slikenet/NativeFeatureIncludes.h"
#if _RAKNET_SUPPORT_TCPInterface==1
#include "slikenet/Export.h"
#include "slikenet/types.h"
#include "slikenet/DS_Queue.h"
#include "slikenet/string.h"
#include "jansson.h"
#ifndef __RACKSPACE_2_H
#define __RACKSPACE_2_H
namespace SLNet
{
class TCPInterface;
class HTTPConnection2;
struct Packet;
enum Rackspace2ResponseCode
{
R2RC_AUTHENTICATED,
R2RC_GOT_DOMAINS,
R2RC_GOT_RECORDS,
R2RC_GOT_SERVERS,
R2RC_GOT_IMAGES,
R2RC_NO_CONTENT,
R2RC_BAD_JSON,
R2RC_UNAUTHORIZED,
R2RC_404_NOT_FOUND,
R2RC_UNKNOWN,
};
/// \brief Callback interface to receive the results of operations
class RAK_DLL_EXPORT Rackspace2EventCallback
{
public:
virtual void OnTCPFailure(void)=0;
virtual void OnTransmissionFailed(HTTPConnection2 *httpConnection2, RakString postStr, RakString authURLDomain)=0;
virtual void OnResponse(Rackspace2ResponseCode r2rc, RakString responseReceived, ptrdiff_t contentOffset)=0;
virtual void OnEmptyResponse(RakString stringTransmitted)=0;
virtual void OnMessage(const char *message, RakString responseReceived, RakString stringTransmitted, ptrdiff_t contentOffset)=0;
};
/// \brief Version 2 of the code that uses the TCPInterface class to communicate with the Rackspace API servers
/// Works with their "next-gen" API as of 2012
/// API operations are hidden at http://docs.rackspace.com/servers/api/v2/cs-devguide/content/ch_api_operations.html
/// \pre Compile RakNet with OPEN_SSL_CLIENT_SUPPORT set to 1
/// Maintains its own TCPInterface class
class RAK_DLL_EXPORT Rackspace2
{
public:
Rackspace2();
~Rackspace2();
// Call periodically
void Update(void);
/// Sets the callback to be used when an operation completes
void SetEventCallback(Rackspace2EventCallback *callback);
int GetCloudAccountNumber(void) const;
const char *GetAuthToken(void) const;
/// \brief Authenticate with Rackspace servers, required before executing any commands.
/// \details All requests to authenticate and operate against Cloud Servers are performed using SSL over HTTP (HTTPS) on TCP port 443.
/// TODO - Will reauthenticate automatically as needed
/// \param[in] authenticationURL See http://docs.rackspace.com/cdns/api/v1.0/cdns-devguide/content/Authentication-d1e647.html
/// \param[in] rackspaceCloudUsername Username you registered with Rackspace on their website
/// \param[in] apiAccessKey Obtain your API access key from the Rackspace Cloud Control Panel in the Your Account API Access section.
void Authenticate(const char *authenticationURL, const char *rackspaceCloudUsername, const char *apiAccessKey);
enum OpType
{
OT_POST,
OT_PUT,
OT_GET,
OT_DELETE,
};
/// \param[in] URL Path to command, for example https://identity.api.rackspacecloud.com/v2.0/tokens
/// \param[in] opType Type of operation to perform
/// \param[in] data If the operation requires data, put it here
/// \param[in] setAuthToken true to automatically set the auth token for the operation. I believe this should be true for everything except authentication itself
void AddOperation(SLNet::RakString URL, OpType opType, json_t *data, bool setAuthToken);
struct Operation
{
SLNet::RakString URL;
bool isPost;
json_t *data;
};
protected:
void AuthenticateInt(const char *authenticationURL, const char *rackspaceCloudUsername, const char *apiAccessKey);
void Reauthenticate(void);
char X_Auth_Token[128];
Rackspace2EventCallback *eventCallback;
DataStructures::Queue<Operation> operations;
TCPInterface *tcp;
HTTPConnection2 *httpConnection2;
int cloudAccountNumber;
RakString lastAuthenticationURL;
RakString lastRackspaceCloudUsername;
RakString lastApiAccessKey;
bool reexecuteLastRequestOnAuth;
//SystemAddress serverAddress;
RakString __addOpLast_URL;
OpType __addOpLast_isPost;
RakString __addOpLast_dataAsStr;
};
} // namespace SLNet
#endif // __RACKSPACE_API_H
#endif // _RAKNET_SUPPORT_Rackspace