Rackspace2.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "Rackspace2.h"
  11. #include "TCPInterface.h"
  12. #include "HTTPConnection2.h"
  13. using namespace RakNet;
  14. Rackspace2::Rackspace2()
  15. {
  16. X_Auth_Token[0]=0;
  17. eventCallback=0;
  18. tcp=0;
  19. cloudAccountNumber=0;
  20. reexecuteLastRequestOnAuth=false;
  21. }
  22. Rackspace2::~Rackspace2()
  23. {
  24. }
  25. void Rackspace2::Update(void)
  26. {
  27. RakString stringTransmitted;
  28. RakString hostTransmitted;
  29. RakString responseReceived;
  30. Packet *packet;
  31. SystemAddress sa;
  32. // This is kind of crappy, but for TCP plugins, always do HasCompletedConnectionAttempt, then Receive(), then HasFailedConnectionAttempt(),HasLostConnection()
  33. sa = tcp->HasCompletedConnectionAttempt();
  34. if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
  35. {
  36. //printf("Rackspace2 TCP: Connected to %s\n", sa.ToString());
  37. // serverAddress = sa;
  38. }
  39. for (packet = tcp->Receive(); packet; tcp->DeallocatePacket(packet), packet = tcp->Receive())
  40. ;
  41. sa = tcp->HasFailedConnectionAttempt();
  42. //if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
  43. // printf("Rackspace2 TCP: Failed connection attempt to %s\n", sa.ToString());
  44. sa = tcp->HasLostConnection();
  45. if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
  46. {
  47. //printf("Rackspace2 TCP: Lost connection to %s\n", sa.ToString());
  48. // serverAddress=UNASSIGNED_SYSTEM_ADDRESS;
  49. }
  50. SystemAddress hostReceived;
  51. int contentOffset;
  52. if (httpConnection2->GetResponse(stringTransmitted, hostTransmitted, responseReceived, hostReceived, contentOffset))
  53. {
  54. if (responseReceived.IsEmpty()==false)
  55. {
  56. static FILE *fp = fopen("responses.txt", "wt");
  57. fprintf(fp, responseReceived.C_String());
  58. fprintf(fp, "\n");
  59. if (contentOffset==-1)
  60. {
  61. if (eventCallback)
  62. eventCallback->OnResponse(R2RC_NO_CONTENT, responseReceived, contentOffset);
  63. }
  64. else
  65. {
  66. json_error_t error;
  67. json_t *root = json_loads(strstr(responseReceived.C_String() + contentOffset, "{"), JSON_REJECT_DUPLICATES | JSON_DISABLE_EOF_CHECK, &error);
  68. if (!root)
  69. {
  70. if (eventCallback)
  71. eventCallback->OnResponse(R2RC_BAD_JSON, responseReceived, contentOffset);
  72. }
  73. else
  74. {
  75. void *iter = json_object_iter(root);
  76. const char *firstKey = json_object_iter_key(iter);
  77. if (stricmp(firstKey, "unauthorized")==0)
  78. {
  79. if (eventCallback)
  80. eventCallback->OnResponse(R2RC_UNAUTHORIZED, responseReceived, contentOffset);
  81. }
  82. else if (stricmp(firstKey, "itemNotFound")==0)
  83. {
  84. if (eventCallback)
  85. eventCallback->OnResponse(R2RC_404_NOT_FOUND, responseReceived, contentOffset);
  86. }
  87. else if (stricmp(firstKey, "access")==0)
  88. {
  89. json_t *valAuthToken = json_object_get(json_object_get(json_object_get(root, "access"), "token"), "id");
  90. strcpy(X_Auth_Token, json_string_value(valAuthToken));
  91. json_t *valAccountNumber = json_object_get(json_object_get(json_object_get(json_object_get(root, "access"), "token"), "tenant"), "id");
  92. cloudAccountNumber = atoi(json_string_value(valAccountNumber));
  93. if (reexecuteLastRequestOnAuth)
  94. {
  95. reexecuteLastRequestOnAuth=false;
  96. json_t *root = json_loads(__addOpLast_dataAsStr.C_String(), 0, &error);
  97. AddOperation(__addOpLast_URL, __addOpLast_isPost, root, true);
  98. }
  99. else
  100. {
  101. if (eventCallback)
  102. eventCallback->OnResponse(R2RC_AUTHENTICATED, responseReceived, contentOffset);
  103. }
  104. }
  105. else if (stricmp(firstKey, "domains")==0)
  106. {
  107. if (eventCallback)
  108. eventCallback->OnResponse(R2RC_GOT_DOMAINS, responseReceived, contentOffset);
  109. }
  110. else if (stricmp(firstKey, "records")==0)
  111. {
  112. if (eventCallback)
  113. eventCallback->OnResponse(R2RC_GOT_RECORDS, responseReceived, contentOffset);
  114. }
  115. else if (stricmp(firstKey, "servers")==0)
  116. {
  117. if (eventCallback)
  118. eventCallback->OnResponse(R2RC_GOT_SERVERS, responseReceived, contentOffset);
  119. }
  120. else if (stricmp(firstKey, "images")==0)
  121. {
  122. if (eventCallback)
  123. eventCallback->OnResponse(R2RC_GOT_IMAGES, responseReceived, contentOffset);
  124. }
  125. else if (stricmp(firstKey, "message")==0)
  126. {
  127. const char *message = json_string_value(json_object_iter_value(iter));
  128. if (strcmp(message, "Invalid authentication token. Please renew.")==0)
  129. {
  130. // Sets reexecuteLastRequestOnAuth to true
  131. // After authenticate completes, will rerun the last run command
  132. Reauthenticate();
  133. }
  134. else
  135. {
  136. if (eventCallback)
  137. eventCallback->OnMessage(message, responseReceived, stringTransmitted, contentOffset);
  138. }
  139. }
  140. else
  141. {
  142. if (eventCallback)
  143. eventCallback->OnResponse(R2RC_UNKNOWN, responseReceived, contentOffset);
  144. }
  145. }
  146. json_decref(root);
  147. }
  148. }
  149. else
  150. {
  151. if (eventCallback)
  152. eventCallback->OnEmptyResponse(stringTransmitted);
  153. }
  154. }
  155. }
  156. void Rackspace2::SetEventCallback(Rackspace2EventCallback *callback)
  157. {
  158. eventCallback=callback;
  159. }
  160. int Rackspace2::GetCloudAccountNumber(void) const
  161. {
  162. return cloudAccountNumber;
  163. }
  164. const char *Rackspace2::GetAuthToken(void) const
  165. {
  166. return (const char*) &X_Auth_Token;
  167. }
  168. void Rackspace2::Reauthenticate(void)
  169. {
  170. reexecuteLastRequestOnAuth=true;
  171. AuthenticateInt(lastAuthenticationURL.C_String(), lastRackspaceCloudUsername.C_String(), lastApiAccessKey.C_String());
  172. }
  173. void Rackspace2::AuthenticateInt(const char *authenticationURL, const char *rackspaceCloudUsername, const char *apiAccessKey)
  174. {
  175. json_t *json_credentials = json_object();
  176. json_object_set(json_credentials, "username", json_string(rackspaceCloudUsername));
  177. json_object_set(json_credentials, "apiKey", json_string(apiAccessKey));
  178. json_t *json_auth = json_object();
  179. json_object_set(json_auth, "RAX-KSKEY:apiKeyCredentials", json_credentials);
  180. json_t *json_root = json_object();
  181. json_object_set(json_root, "auth", json_auth);
  182. RakString URL = authenticationURL;
  183. RakString command = "/tokens";
  184. URL += command;
  185. AddOperation(URL, OT_POST, json_root, false);
  186. }
  187. void Rackspace2::Authenticate(const char *authenticationURL, const char *rackspaceCloudUsername, const char *apiAccessKey)
  188. {
  189. lastAuthenticationURL=authenticationURL;
  190. lastRackspaceCloudUsername=rackspaceCloudUsername;
  191. lastApiAccessKey=apiAccessKey;
  192. AuthenticateInt(authenticationURL, rackspaceCloudUsername,apiAccessKey);
  193. }
  194. void Rackspace2::AddOperation(RakNet::RakString URL, OpType opType, json_t *data, bool setAuthToken)
  195. {
  196. if (tcp==0)
  197. {
  198. tcp = RakNet::OP_NEW<TCPInterface>(_FILE_AND_LINE_);
  199. if (tcp->Start(0, 0, 8)==false)
  200. {
  201. if (eventCallback)
  202. eventCallback->OnTCPFailure();
  203. }
  204. httpConnection2 = RakNet::OP_NEW<HTTPConnection2>(_FILE_AND_LINE_);
  205. tcp->AttachPlugin(httpConnection2);
  206. }
  207. RakString authURLHeader, authURLDomain, authURLPath;
  208. URL.SplitURI(authURLHeader,authURLDomain,authURLPath);
  209. char *jsonStr = "";
  210. if (data)
  211. jsonStr = json_dumps(data, 0);
  212. RakString requestStr;
  213. RakString extraBody;
  214. if (setAuthToken)
  215. {
  216. RakAssert(X_Auth_Token[0]);
  217. // Test expired token
  218. //strcpy(X_Auth_Token, "fd6ad67c-fbd3-4b35-94e2-059b6090998e");
  219. extraBody.Set("Accept: application/json\r\nX-Auth-Token: %s", X_Auth_Token);
  220. __addOpLast_URL = URL;
  221. __addOpLast_isPost = opType;
  222. __addOpLast_dataAsStr = jsonStr;
  223. }
  224. else
  225. {
  226. extraBody = "Accept: application/json";
  227. }
  228. if (opType==OT_POST)
  229. requestStr = RakString::FormatForPOST(URL, "application/json", jsonStr, extraBody);
  230. else if (opType==OT_GET)
  231. requestStr = RakString::FormatForGET(URL, extraBody);
  232. else if (opType==OT_DELETE)
  233. requestStr = RakString::FormatForDELETE(URL, extraBody);
  234. else
  235. requestStr = RakString::FormatForPUT(URL, "application/json", jsonStr, extraBody);
  236. bool b = httpConnection2->TransmitRequest(requestStr,authURLDomain, 443, true);
  237. if (!b)
  238. {
  239. if (eventCallback)
  240. eventCallback->OnTransmissionFailed(httpConnection2, requestStr, authURLDomain);
  241. }
  242. if (data)
  243. {
  244. free(jsonStr);
  245. json_decref(data);
  246. }
  247. }
粤ICP备19079148号