Rackspace.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  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 "NativeFeatureIncludes.h"
  11. #if _RAKNET_SUPPORT_Rackspace==1 && _RAKNET_SUPPORT_TCPInterface==1
  12. #include "Rackspace.h"
  13. #include "RakString.h"
  14. #include "TCPInterface.h"
  15. using namespace RakNet;
  16. Rackspace::Rackspace()
  17. {
  18. tcpInterface=0;
  19. }
  20. Rackspace::~Rackspace()
  21. {
  22. }
  23. void Rackspace::AddEventCallback(Rackspace2EventCallback *callback)
  24. {
  25. unsigned int idx = eventCallbacks.GetIndexOf(callback);
  26. if (idx == (unsigned int)-1)
  27. eventCallbacks.Push(callback,_FILE_AND_LINE_);
  28. }
  29. void Rackspace::RemoveEventCallback(Rackspace2EventCallback *callback)
  30. {
  31. unsigned int idx = eventCallbacks.GetIndexOf(callback);
  32. if (idx != (unsigned int)-1)
  33. eventCallbacks.RemoveAtIndex(idx);
  34. }
  35. void Rackspace::ClearEventCallbacks(void)
  36. {
  37. eventCallbacks.Clear(true, _FILE_AND_LINE_);
  38. }
  39. SystemAddress Rackspace::Authenticate(TCPInterface *_tcpInterface, const char *_authenticationURL, const char *_rackspaceCloudUsername, const char *_apiAccessKey)
  40. {
  41. unsigned int index = GetOperationOfTypeIndex(RO_CONNECT_AND_AUTHENTICATE);
  42. if (index!=(unsigned int)-1)
  43. {
  44. // In progress
  45. return operations[index].connectionAddress;
  46. }
  47. tcpInterface=_tcpInterface;
  48. rackspaceCloudUsername=_rackspaceCloudUsername;
  49. apiAccessKey=_apiAccessKey;
  50. unsigned int i;
  51. RackspaceOperation ro;
  52. ro.type=RO_CONNECT_AND_AUTHENTICATE;
  53. ro.isPendingAuthentication=false;
  54. RakAssert(tcpInterface->WasStarted());
  55. ro.connectionAddress=tcpInterface->Connect(_authenticationURL,443,true);
  56. if (ro.connectionAddress==UNASSIGNED_SYSTEM_ADDRESS)
  57. {
  58. for (i=0; i < eventCallbacks.Size(); i++)
  59. eventCallbacks[i]->OnConnectionAttemptFailure(RO_CONNECT_AND_AUTHENTICATE, _authenticationURL);
  60. return UNASSIGNED_SYSTEM_ADDRESS;
  61. }
  62. #if OPEN_SSL_CLIENT_SUPPORT==1
  63. tcpInterface->StartSSLClient(ro.connectionAddress);
  64. #endif
  65. RakNet::RakString command(
  66. "GET /v1.0 HTTP/1.1\n"
  67. "Host: %s\n"
  68. "X-Auth-User: %s\n"
  69. "X-Auth-Key: %s\n\n"
  70. ,_authenticationURL, _rackspaceCloudUsername, _apiAccessKey);
  71. tcpInterface->Send(command.C_String(), (unsigned int) command.GetLength(), ro.connectionAddress, false);
  72. operations.Insert(ro,_FILE_AND_LINE_);
  73. return ro.connectionAddress;
  74. }
  75. const char * Rackspace::EventTypeToString(RackspaceEventType eventType)
  76. {
  77. switch (eventType)
  78. {
  79. case RET_Success_200:
  80. return "Success_200";
  81. case RET_Success_201:
  82. return "Success_201";
  83. case RET_Success_202:
  84. return "Success_202";
  85. case RET_Success_203:
  86. return "Success_203";
  87. case RET_Success_204:
  88. return "Success_204";
  89. case RET_Cloud_Servers_Fault_500:
  90. return "Cloud_Servers_Fault_500";
  91. case RET_Service_Unavailable_503:
  92. return "Service_Unavailable_503";
  93. case RET_Unauthorized_401:
  94. return "Unauthorized_401";
  95. case RET_Bad_Request_400:
  96. return "Bad_Request_400";
  97. case RET_Over_Limit_413:
  98. return "Over_Limit_413";
  99. case RET_Bad_Media_Type_415:
  100. return "Bad_Media_Type_415";
  101. case RET_Item_Not_Found_404:
  102. return "Item_Not_Found_404";
  103. case RET_Build_In_Progress_409:
  104. return "Build_In_Progress_409";
  105. case RET_Resize_Not_Allowed_403:
  106. return "Resize_Not_Allowed_403";
  107. case RET_Connection_Closed_Without_Reponse:
  108. return "Connection_Closed_Without_Reponse";
  109. case RET_Unknown_Failure:
  110. return "Unknown_Failure";
  111. }
  112. return "Unknown event type (bug)";
  113. }
  114. void Rackspace::AddOperation(RackspaceOperationType type, RakNet::RakString httpCommand, RakNet::RakString operation, RakNet::RakString xml)
  115. {
  116. RackspaceOperation ro;
  117. ro.type=type;
  118. ro.httpCommand=httpCommand;
  119. ro.operation=operation;
  120. ro.xml=xml;
  121. ro.isPendingAuthentication=HasOperationOfType(RO_CONNECT_AND_AUTHENTICATE);
  122. if (ro.isPendingAuthentication==false)
  123. {
  124. if (ExecuteOperation(ro))
  125. operations.Insert(ro,_FILE_AND_LINE_);
  126. }
  127. else
  128. operations.Insert(ro,_FILE_AND_LINE_);
  129. }
  130. void Rackspace::ListServers(void)
  131. {
  132. AddOperation(RO_LIST_SERVERS, "GET", "servers", "");
  133. }
  134. void Rackspace::ListServersWithDetails(void)
  135. {
  136. AddOperation(RO_LIST_SERVERS_WITH_DETAILS, "GET", "servers/detail", "");
  137. }
  138. void Rackspace::CreateServer(RakNet::RakString name, RakNet::RakString imageId, RakNet::RakString flavorId)
  139. {
  140. RakNet::RakString xml(
  141. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  142. "<server xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" name=\"%s\" imageId=\"%s\" flavorId=\"%s\">"
  143. "</server>"
  144. ,name.C_String() ,imageId.C_String(), flavorId.C_String());
  145. AddOperation(RO_CREATE_SERVER, "POST", "servers", xml);
  146. }
  147. void Rackspace::GetServerDetails(RakNet::RakString serverId)
  148. {
  149. AddOperation(RO_GET_SERVER_DETAILS, "GET", RakNet::RakString("servers/%s", serverId.C_String()), "");
  150. }
  151. void Rackspace::UpdateServerNameOrPassword(RakNet::RakString serverId, RakNet::RakString newName, RakNet::RakString newPassword)
  152. {
  153. if (newName.IsEmpty() && newPassword.IsEmpty())
  154. return;
  155. RakNet::RakString xml(
  156. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  157. "<server xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\""
  158. );
  159. if (newName.IsEmpty()==false)
  160. xml += RakNet::RakString(" name=\"%s\"", newName.C_String());
  161. if (newPassword.IsEmpty()==false)
  162. xml += RakNet::RakString(" adminPass=\"%s\"", newPassword.C_String());
  163. xml += " />";
  164. AddOperation(RO_UPDATE_SERVER_NAME_OR_PASSWORD, "PUT", RakNet::RakString("servers/%s", serverId.C_String()), xml);
  165. }
  166. void Rackspace::DeleteServer(RakNet::RakString serverId)
  167. {
  168. AddOperation(RO_DELETE_SERVER, "DELETE", RakNet::RakString("servers/%s", serverId.C_String()), "");
  169. }
  170. void Rackspace::ListServerAddresses(RakNet::RakString serverId)
  171. {
  172. AddOperation(RO_LIST_SERVER_ADDRESSES, "GET", RakNet::RakString("servers/%s/ips", serverId.C_String()), "");
  173. }
  174. void Rackspace::ShareServerAddress(RakNet::RakString serverId, RakNet::RakString ipAddress)
  175. {
  176. AddOperation(RO_SHARE_SERVER_ADDRESS, "PUT", RakNet::RakString("servers/%s/ips/public/%s", serverId.C_String(), ipAddress.C_String()), "");
  177. }
  178. void Rackspace::DeleteServerAddress(RakNet::RakString serverId, RakNet::RakString ipAddress)
  179. {
  180. AddOperation(RO_DELETE_SERVER_ADDRESS, "DELETE", RakNet::RakString("servers/%s/ips/public/%s", serverId.C_String(), ipAddress.C_String()), "");
  181. }
  182. void Rackspace::RebootServer(RakNet::RakString serverId, RakNet::RakString rebootType)
  183. {
  184. RakNet::RakString xml(
  185. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  186. "<reboot xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" type=\"%s\""
  187. "/>",
  188. rebootType.C_String());
  189. AddOperation(RO_REBOOT_SERVER, "POST", RakNet::RakString("servers/%s/action", serverId.C_String()), xml);
  190. }
  191. void Rackspace::RebuildServer(RakNet::RakString serverId, RakNet::RakString imageId)
  192. {
  193. RakNet::RakString xml(
  194. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  195. "<rebuild xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" imageId=\"%s\""
  196. "/>",
  197. imageId.C_String());
  198. AddOperation(RO_REBUILD_SERVER, "POST", RakNet::RakString("servers/%s/action", serverId.C_String()), xml);
  199. }
  200. void Rackspace::ResizeServer(RakNet::RakString serverId, RakNet::RakString flavorId)
  201. {
  202. RakNet::RakString xml(
  203. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  204. "<resize xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" flavorId=\"%s\""
  205. "/>",
  206. flavorId.C_String());
  207. AddOperation(RO_RESIZE_SERVER, "POST", RakNet::RakString("servers/%s/action", serverId.C_String()), xml);
  208. }
  209. void Rackspace::ConfirmResizedServer(RakNet::RakString serverId)
  210. {
  211. RakNet::RakString xml(
  212. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  213. "<confirmResize xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" "
  214. "/>");
  215. AddOperation(RO_CONFIRM_RESIZED_SERVER, "POST", RakNet::RakString("servers/%s/action", serverId.C_String()), xml);
  216. }
  217. void Rackspace::RevertResizedServer(RakNet::RakString serverId)
  218. {
  219. RakNet::RakString xml(
  220. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  221. "<revertResize xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" "
  222. "/>");
  223. AddOperation(RO_REVERT_RESIZED_SERVER, "POST", RakNet::RakString("servers/%s/action", serverId.C_String()), xml);
  224. }
  225. void Rackspace::ListFlavors(void)
  226. {
  227. AddOperation(RO_LIST_FLAVORS, "GET", "flavors", "");
  228. }
  229. void Rackspace::GetFlavorDetails(RakNet::RakString flavorId)
  230. {
  231. AddOperation(RO_GET_FLAVOR_DETAILS, "GET", RakNet::RakString("flavors/%s", flavorId.C_String()), "");
  232. }
  233. void Rackspace::ListImages(void)
  234. {
  235. AddOperation(RO_LIST_IMAGES, "GET", "images", "");
  236. }
  237. void Rackspace::CreateImage(RakNet::RakString serverId, RakNet::RakString imageName)
  238. {
  239. RakNet::RakString xml(
  240. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  241. "<image xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" name=\"%s\" serverId=\"%s\""
  242. "/>",
  243. imageName.C_String(),serverId.C_String());
  244. AddOperation(RO_CREATE_IMAGE, "POST", "images", xml);
  245. }
  246. void Rackspace::GetImageDetails(RakNet::RakString imageId)
  247. {
  248. AddOperation(RO_GET_IMAGE_DETAILS, "GET", RakNet::RakString("images/%s", imageId.C_String()), "");
  249. }
  250. void Rackspace::DeleteImage(RakNet::RakString imageId)
  251. {
  252. AddOperation(RO_DELETE_IMAGE, "DELETE", RakNet::RakString("images/%s", imageId.C_String()), "");
  253. }
  254. void Rackspace::ListSharedIPGroups(void)
  255. {
  256. AddOperation(RO_LIST_SHARED_IP_GROUPS, "GET", "shared_ip_groups", "");
  257. }
  258. void Rackspace::ListSharedIPGroupsWithDetails(void)
  259. {
  260. AddOperation(RO_LIST_SHARED_IP_GROUPS_WITH_DETAILS, "GET", "shared_ip_groups/detail", "");
  261. }
  262. void Rackspace::CreateSharedIPGroup(RakNet::RakString name, RakNet::RakString optionalServerId)
  263. {
  264. RakNet::RakString xml(
  265. "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  266. "<sharedIpGroup xmlns=\"http://docs.rackspacecloud.com/servers/api/v1.0\" name=\"%s\">", name.C_String());
  267. if (optionalServerId.IsEmpty()==false)
  268. xml+=RakNet::RakString("<server id=\"%s\"/>", optionalServerId.C_String());
  269. xml+="</sharedIpGroup>";
  270. AddOperation(RO_CREATE_SHARED_IP_GROUP, "POST", "shared_ip_groups", xml);
  271. }
  272. void Rackspace::GetSharedIPGroupDetails(RakNet::RakString groupId)
  273. {
  274. AddOperation(RO_GET_SHARED_IP_GROUP_DETAILS, "GET", RakNet::RakString("shared_ip_groups/%s", groupId.C_String()), "");
  275. }
  276. void Rackspace::DeleteSharedIPGroup(RakNet::RakString groupId)
  277. {
  278. AddOperation(RO_DELETE_SHARED_IP_GROUP, "DELETE", RakNet::RakString("shared_ip_groups/%s", groupId.C_String()), "");
  279. }
  280. void Rackspace::OnClosedConnection(SystemAddress systemAddress)
  281. {
  282. if (systemAddress==UNASSIGNED_SYSTEM_ADDRESS)
  283. return;
  284. unsigned int i, operationsIndex;
  285. operationsIndex=0;
  286. while (operationsIndex < operations.Size())
  287. {
  288. if (operations[operationsIndex].isPendingAuthentication==false && operations[operationsIndex].connectionAddress==systemAddress)
  289. {
  290. RackspaceOperation ro = operations[operationsIndex];
  291. operations.RemoveAtIndex(operationsIndex);
  292. RakNet::RakString packetDataString = ro.incomingStream;
  293. const char *packetData = packetDataString.C_String();
  294. char resultCodeStr[32];
  295. int resultCodeInt;
  296. RackspaceEventType rackspaceEventType;
  297. char *result;
  298. result=strstr((char*) packetData, "HTTP/1.1 ");
  299. if (result!=0)
  300. {
  301. result+=strlen("HTTP/1.1 ");
  302. for (i=0; i < sizeof(resultCodeStr)-1 && result[i] && result[i]>='0' && result[i]<='9'; i++)
  303. resultCodeStr[i]=result[i];
  304. resultCodeStr[i]=0;
  305. resultCodeInt=atoi(resultCodeStr);
  306. switch (resultCodeInt)
  307. {
  308. case 200: rackspaceEventType=RET_Success_200; break;
  309. case 201: rackspaceEventType=RET_Success_201; break;
  310. case 202: rackspaceEventType=RET_Success_202; break;
  311. case 203: rackspaceEventType=RET_Success_203; break;
  312. case 204: rackspaceEventType=RET_Success_204; break;
  313. case 500: rackspaceEventType=RET_Cloud_Servers_Fault_500; break;
  314. case 503: rackspaceEventType=RET_Service_Unavailable_503; break;
  315. case 401: rackspaceEventType=RET_Unauthorized_401; break;
  316. case 400: rackspaceEventType=RET_Bad_Request_400; break;
  317. case 413: rackspaceEventType=RET_Over_Limit_413; break;
  318. case 415: rackspaceEventType=RET_Bad_Media_Type_415; break;
  319. case 404: rackspaceEventType=RET_Item_Not_Found_404; break;
  320. case 409: rackspaceEventType=RET_Build_In_Progress_409; break;
  321. case 403: rackspaceEventType=RET_Resize_Not_Allowed_403; break;
  322. default: rackspaceEventType=RET_Unknown_Failure; break;
  323. }
  324. }
  325. else
  326. {
  327. rackspaceEventType=RET_Connection_Closed_Without_Reponse;
  328. }
  329. switch (ro.type)
  330. {
  331. case RO_CONNECT_AND_AUTHENTICATE:
  332. {
  333. if (rackspaceEventType==RET_Success_204)
  334. {
  335. RakNet::RakString header;
  336. ReadLine(packetData, "X-Server-Management-Url: ", serverManagementURL);
  337. serverManagementURL.SplitURI(header, serverManagementDomain, serverManagementPath);
  338. ReadLine(packetData, "X-Storage-Url: ", storageURL);
  339. storageURL.SplitURI(header, storageDomain, storagePath);
  340. ReadLine(packetData, "X-CDN-Management-Url: ", cdnManagementURL);
  341. cdnManagementURL.SplitURI(header, cdnManagementDomain, cdnManagementPath);
  342. ReadLine(packetData, "X-Auth-Token: ", authToken);
  343. ReadLine(packetData, "X-Storage-Token: ", storageToken);
  344. operationsIndex=0;
  345. while (operationsIndex < operations.Size())
  346. {
  347. if (operations[operationsIndex].isPendingAuthentication==true)
  348. {
  349. operations[operationsIndex].isPendingAuthentication=false;
  350. if (ExecuteOperation(operations[operationsIndex])==false)
  351. {
  352. operations.RemoveAtIndex(operationsIndex);
  353. }
  354. else
  355. operationsIndex++;
  356. }
  357. else
  358. operationsIndex++;
  359. }
  360. // Restart in list
  361. operationsIndex=0;
  362. }
  363. for (i=0; i < eventCallbacks.Size(); i++)
  364. eventCallbacks[i]->OnAuthenticationResult(rackspaceEventType, (const char*) packetData);
  365. break;
  366. }
  367. case RO_LIST_SERVERS:
  368. {
  369. for (i=0; i < eventCallbacks.Size(); i++)
  370. eventCallbacks[i]->OnListServersResult(rackspaceEventType, (const char*) packetData);
  371. break;
  372. }
  373. case RO_LIST_SERVERS_WITH_DETAILS:
  374. {
  375. for (i=0; i < eventCallbacks.Size(); i++)
  376. eventCallbacks[i]->OnListServersWithDetailsResult(rackspaceEventType, (const char*) packetData);
  377. break;
  378. }
  379. case RO_CREATE_SERVER:
  380. {
  381. for (i=0; i < eventCallbacks.Size(); i++)
  382. eventCallbacks[i]->OnCreateServerResult(rackspaceEventType, (const char*) packetData);
  383. break;
  384. }
  385. case RO_GET_SERVER_DETAILS:
  386. {
  387. for (i=0; i < eventCallbacks.Size(); i++)
  388. eventCallbacks[i]->OnGetServerDetails(rackspaceEventType, (const char*) packetData);
  389. break;
  390. }
  391. case RO_UPDATE_SERVER_NAME_OR_PASSWORD:
  392. {
  393. for (i=0; i < eventCallbacks.Size(); i++)
  394. eventCallbacks[i]->OnUpdateServerNameOrPassword(rackspaceEventType, (const char*) packetData);
  395. break;
  396. }
  397. case RO_DELETE_SERVER:
  398. {
  399. for (i=0; i < eventCallbacks.Size(); i++)
  400. eventCallbacks[i]->OnDeleteServer(rackspaceEventType, (const char*) packetData);
  401. break;
  402. }
  403. case RO_LIST_SERVER_ADDRESSES:
  404. {
  405. for (i=0; i < eventCallbacks.Size(); i++)
  406. eventCallbacks[i]->OnListServerAddresses(rackspaceEventType, (const char*) packetData);
  407. break;
  408. }
  409. case RO_SHARE_SERVER_ADDRESS:
  410. {
  411. for (i=0; i < eventCallbacks.Size(); i++)
  412. eventCallbacks[i]->OnShareServerAddress(rackspaceEventType, (const char*) packetData);
  413. break;
  414. }
  415. case RO_DELETE_SERVER_ADDRESS:
  416. {
  417. for (i=0; i < eventCallbacks.Size(); i++)
  418. eventCallbacks[i]->OnDeleteServerAddress(rackspaceEventType, (const char*) packetData);
  419. break;
  420. }
  421. case RO_REBOOT_SERVER:
  422. {
  423. for (i=0; i < eventCallbacks.Size(); i++)
  424. eventCallbacks[i]->OnRebootServer(rackspaceEventType, (const char*) packetData);
  425. break;
  426. }
  427. case RO_REBUILD_SERVER:
  428. {
  429. for (i=0; i < eventCallbacks.Size(); i++)
  430. eventCallbacks[i]->OnRebuildServer(rackspaceEventType, (const char*) packetData);
  431. break;
  432. }
  433. case RO_RESIZE_SERVER:
  434. {
  435. for (i=0; i < eventCallbacks.Size(); i++)
  436. eventCallbacks[i]->OnResizeServer(rackspaceEventType, (const char*) packetData);
  437. break;
  438. }
  439. case RO_CONFIRM_RESIZED_SERVER:
  440. {
  441. for (i=0; i < eventCallbacks.Size(); i++)
  442. eventCallbacks[i]->OnConfirmResizedServer(rackspaceEventType, (const char*) packetData);
  443. break;
  444. }
  445. case RO_REVERT_RESIZED_SERVER:
  446. {
  447. for (i=0; i < eventCallbacks.Size(); i++)
  448. eventCallbacks[i]->OnRevertResizedServer(rackspaceEventType, (const char*) packetData);
  449. break;
  450. }
  451. case RO_LIST_FLAVORS:
  452. {
  453. for (i=0; i < eventCallbacks.Size(); i++)
  454. eventCallbacks[i]->OnListFlavorsResult(rackspaceEventType, (const char*) packetData);
  455. break;
  456. }
  457. case RO_GET_FLAVOR_DETAILS:
  458. {
  459. for (i=0; i < eventCallbacks.Size(); i++)
  460. eventCallbacks[i]->OnGetFlavorDetailsResult(rackspaceEventType, (const char*) packetData);
  461. break;
  462. }
  463. case RO_LIST_IMAGES:
  464. {
  465. for (i=0; i < eventCallbacks.Size(); i++)
  466. eventCallbacks[i]->OnListImagesResult(rackspaceEventType, (const char*) packetData);
  467. break;
  468. }
  469. case RO_CREATE_IMAGE:
  470. {
  471. for (i=0; i < eventCallbacks.Size(); i++)
  472. eventCallbacks[i]->OnCreateImageResult(rackspaceEventType, (const char*) packetData);
  473. break;
  474. }
  475. case RO_GET_IMAGE_DETAILS:
  476. {
  477. for (i=0; i < eventCallbacks.Size(); i++)
  478. eventCallbacks[i]->OnGetImageDetailsResult(rackspaceEventType, (const char*) packetData);
  479. break;
  480. }
  481. case RO_DELETE_IMAGE:
  482. {
  483. for (i=0; i < eventCallbacks.Size(); i++)
  484. eventCallbacks[i]->OnDeleteImageResult(rackspaceEventType, (const char*) packetData);
  485. break;
  486. }
  487. case RO_LIST_SHARED_IP_GROUPS:
  488. {
  489. for (i=0; i < eventCallbacks.Size(); i++)
  490. eventCallbacks[i]->OnListSharedIPGroups(rackspaceEventType, (const char*) packetData);
  491. break;
  492. }
  493. case RO_LIST_SHARED_IP_GROUPS_WITH_DETAILS:
  494. {
  495. for (i=0; i < eventCallbacks.Size(); i++)
  496. eventCallbacks[i]->OnListSharedIPGroupsWithDetails(rackspaceEventType, (const char*) packetData);
  497. break;
  498. }
  499. case RO_CREATE_SHARED_IP_GROUP:
  500. {
  501. for (i=0; i < eventCallbacks.Size(); i++)
  502. eventCallbacks[i]->OnCreateSharedIPGroup(rackspaceEventType, (const char*) packetData);
  503. break;
  504. }
  505. case RO_GET_SHARED_IP_GROUP_DETAILS:
  506. {
  507. for (i=0; i < eventCallbacks.Size(); i++)
  508. eventCallbacks[i]->OnGetSharedIPGroupDetails(rackspaceEventType, (const char*) packetData);
  509. break;
  510. }
  511. case RO_DELETE_SHARED_IP_GROUP:
  512. {
  513. for (i=0; i < eventCallbacks.Size(); i++)
  514. eventCallbacks[i]->OnDeleteSharedIPGroup(rackspaceEventType, (const char*) packetData);
  515. break;
  516. }
  517. default:
  518. break;
  519. }
  520. }
  521. else
  522. {
  523. operationsIndex++;
  524. }
  525. }
  526. }
  527. void Rackspace::OnReceive(Packet *packet)
  528. {
  529. unsigned int operationsIndex;
  530. for (operationsIndex=0; operationsIndex < operations.Size(); operationsIndex++)
  531. {
  532. if (operations[operationsIndex].isPendingAuthentication==false && operations[operationsIndex].connectionAddress==packet->systemAddress)
  533. {
  534. operations[operationsIndex].incomingStream+=packet->data;
  535. }
  536. }
  537. }
  538. bool Rackspace::ExecuteOperation(RackspaceOperation &ro)
  539. {
  540. if (ConnectToServerManagementDomain(ro)==false)
  541. return false;
  542. RakNet::RakString command(
  543. "%s %s/%s HTTP/1.1\n"
  544. "Host: %s\n"
  545. "Content-Type: application/xml\n"
  546. "Content-Length: %i\n"
  547. "Accept: application/xml\n"
  548. "X-Auth-Token: %s\n",
  549. ro.httpCommand.C_String(), serverManagementPath.C_String(), ro.operation.C_String(), serverManagementDomain.C_String(),
  550. ro.xml.GetLength(),
  551. authToken.C_String());
  552. if (ro.xml.IsEmpty()==false)
  553. {
  554. command+="\n";
  555. command+=ro.xml;
  556. command+="\n";
  557. }
  558. command+="\n";
  559. //printf(command.C_String());
  560. tcpInterface->Send(command.C_String(), (unsigned int) command.GetLength(), ro.connectionAddress, false);
  561. return true;
  562. }
  563. void Rackspace::ReadLine(const char *data, const char *stringStart, RakNet::RakString &output)
  564. {
  565. output.Clear();
  566. char *result, *resultEnd;
  567. result=strstr((char*) data, stringStart);
  568. if (result==0)
  569. {
  570. RakAssert(0);
  571. return;
  572. }
  573. result+=strlen(stringStart);
  574. if (result==0)
  575. {
  576. RakAssert(0);
  577. return;
  578. }
  579. output=result;
  580. resultEnd=result;
  581. while (*resultEnd && (*resultEnd!='\r') && (*resultEnd!='\n') )
  582. resultEnd++;
  583. output.Truncate((unsigned int) (resultEnd-result));
  584. }
  585. bool Rackspace::ConnectToServerManagementDomain(RackspaceOperation &ro)
  586. {
  587. unsigned int i;
  588. ro.connectionAddress=tcpInterface->Connect(serverManagementDomain.C_String(),443,true);
  589. if (ro.connectionAddress==UNASSIGNED_SYSTEM_ADDRESS)
  590. {
  591. for (i=0; i < eventCallbacks.Size(); i++)
  592. eventCallbacks[i]->OnConnectionAttemptFailure(ro.type, serverManagementURL);
  593. return false;
  594. }
  595. #if OPEN_SSL_CLIENT_SUPPORT==1
  596. tcpInterface->StartSSLClient(ro.connectionAddress);
  597. #endif
  598. return true;
  599. }
  600. bool Rackspace::HasOperationOfType(RackspaceOperationType t)
  601. {
  602. unsigned int i;
  603. for (i=0; i < operations.Size(); i++)
  604. {
  605. if (operations[i].type==t)
  606. return true;
  607. }
  608. return false;
  609. }
  610. unsigned int Rackspace::GetOperationOfTypeIndex(RackspaceOperationType t)
  611. {
  612. unsigned int i;
  613. for (i=0; i < operations.Size(); i++)
  614. {
  615. if (operations[i].type==t)
  616. return i;
  617. }
  618. return (unsigned int) -1;
  619. }
  620. #endif
粤ICP备19079148号