SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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