service.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /** **************************************************************************
  2. * service.c
  3. *
  4. * Copyright 2008 Bryan Ischo <[email protected]>
  5. *
  6. * This file is part of libs3.
  7. *
  8. * libs3 is free software: you can redistribute it and/or modify it under the
  9. * terms of the GNU Lesser General Public License as published by the Free
  10. * Software Foundation, version 3 or above of the License. You can also
  11. * redistribute and/or modify it under the terms of the GNU General Public
  12. * License, version 2 or above of the License.
  13. *
  14. * In addition, as a special exception, the copyright holders give
  15. * permission to link the code of this library and its programs with the
  16. * OpenSSL library, and distribute linked combinations including the two.
  17. *
  18. * libs3 is distributed in the hope that it will be useful, but WITHOUT ANY
  19. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  21. * details.
  22. *
  23. * You should have received a copy of the GNU Lesser General Public License
  24. * version 3 along with libs3, in a file named COPYING. If not, see
  25. * <http://www.gnu.org/licenses/>.
  26. *
  27. * You should also have received a copy of the GNU General Public License
  28. * version 2 along with libs3, in a file named COPYING-GPLv2. If not, see
  29. * <http://www.gnu.org/licenses/>.
  30. *
  31. ************************************************************************** **/
  32. #include <ctype.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <time.h>
  36. #include "request.h"
  37. typedef struct XmlCallbackData
  38. {
  39. SimpleXml simpleXml;
  40. S3ResponsePropertiesCallback *responsePropertiesCallback;
  41. S3ListServiceCallback *listServiceCallback;
  42. S3ResponseCompleteCallback *responseCompleteCallback;
  43. void *callbackData;
  44. string_buffer(ownerId, 256);
  45. string_buffer(ownerDisplayName, 256);
  46. string_buffer(bucketName, 256);
  47. string_buffer(creationDate, 128);
  48. } XmlCallbackData;
  49. static S3Status xmlCallback(const char *elementPath, const char *data,
  50. int dataLen, void *callbackData)
  51. {
  52. XmlCallbackData *cbData = (XmlCallbackData *) callbackData;
  53. int fit;
  54. if (data) {
  55. if (!strcmp(elementPath, "ListAllMyBucketsResult/Owner/ID")) {
  56. string_buffer_append(cbData->ownerId, data, dataLen, fit);
  57. }
  58. else if (!strcmp(elementPath,
  59. "ListAllMyBucketsResult/Owner/DisplayName")) {
  60. string_buffer_append(cbData->ownerDisplayName, data, dataLen, fit);
  61. }
  62. else if (!strcmp(elementPath,
  63. "ListAllMyBucketsResult/Buckets/Bucket/Name")) {
  64. string_buffer_append(cbData->bucketName, data, dataLen, fit);
  65. }
  66. else if (!strcmp
  67. (elementPath,
  68. "ListAllMyBucketsResult/Buckets/Bucket/CreationDate")) {
  69. string_buffer_append(cbData->creationDate, data, dataLen, fit);
  70. }
  71. }
  72. else {
  73. if (!strcmp(elementPath, "ListAllMyBucketsResult/Buckets/Bucket")) {
  74. // Parse date. Assume ISO-8601 date format.
  75. time_t creationDate = parseIso8601Time(cbData->creationDate);
  76. // Make the callback - a bucket just finished
  77. S3Status status = (*(cbData->listServiceCallback))
  78. (cbData->ownerId, cbData->ownerDisplayName,
  79. cbData->bucketName, creationDate, cbData->callbackData);
  80. string_buffer_initialize(cbData->bucketName);
  81. string_buffer_initialize(cbData->creationDate);
  82. return status;
  83. }
  84. }
  85. /* Avoid compiler error about variable set but not used */
  86. (void) fit;
  87. return S3StatusOK;
  88. }
  89. static S3Status propertiesCallback
  90. (const S3ResponseProperties *responseProperties, void *callbackData)
  91. {
  92. XmlCallbackData *cbData = (XmlCallbackData *) callbackData;
  93. return (*(cbData->responsePropertiesCallback))
  94. (responseProperties, cbData->callbackData);
  95. }
  96. static S3Status dataCallback(int bufferSize, const char *buffer,
  97. void *callbackData)
  98. {
  99. XmlCallbackData *cbData = (XmlCallbackData *) callbackData;
  100. return simplexml_add(&(cbData->simpleXml), buffer, bufferSize);
  101. }
  102. static void completeCallback(S3Status requestStatus,
  103. const S3ErrorDetails *s3ErrorDetails,
  104. void *callbackData)
  105. {
  106. XmlCallbackData *cbData = (XmlCallbackData *) callbackData;
  107. (*(cbData->responseCompleteCallback))
  108. (requestStatus, s3ErrorDetails, cbData->callbackData);
  109. simplexml_deinitialize(&(cbData->simpleXml));
  110. free(cbData);
  111. }
  112. void S3_list_service(S3Protocol protocol, const char *accessKeyId,
  113. const char *secretAccessKey, const char *securityToken,
  114. const char *hostName, const char *authRegion,
  115. S3RequestContext *requestContext,
  116. int timeoutMs,
  117. const S3ListServiceHandler *handler, void *callbackData)
  118. {
  119. // Create and set up the callback data
  120. XmlCallbackData *data =
  121. (XmlCallbackData *) malloc(sizeof(XmlCallbackData));
  122. if (!data) {
  123. (*(handler->responseHandler.completeCallback))
  124. (S3StatusOutOfMemory, 0, callbackData);
  125. return;
  126. }
  127. simplexml_initialize(&(data->simpleXml), &xmlCallback, data);
  128. data->responsePropertiesCallback =
  129. handler->responseHandler.propertiesCallback;
  130. data->listServiceCallback = handler->listServiceCallback;
  131. data->responseCompleteCallback = handler->responseHandler.completeCallback;
  132. data->callbackData = callbackData;
  133. string_buffer_initialize(data->ownerId);
  134. string_buffer_initialize(data->ownerDisplayName);
  135. string_buffer_initialize(data->bucketName);
  136. string_buffer_initialize(data->creationDate);
  137. // Set up the RequestParams
  138. RequestParams params =
  139. {
  140. HttpRequestTypeGET, // httpRequestType
  141. { hostName, // hostName
  142. 0, // bucketName
  143. protocol, // protocol
  144. S3UriStylePath, // uriStyle
  145. accessKeyId, // accessKeyId
  146. secretAccessKey, // secretAccessKey
  147. securityToken, // securityToken
  148. authRegion }, // authRegion
  149. 0, // key
  150. 0, // queryParams
  151. 0, // subResource
  152. 0, // copySourceBucketName
  153. 0, // copySourceKey
  154. 0, // getConditions
  155. 0, // startByte
  156. 0, // byteCount
  157. 0, // requestProperties
  158. &propertiesCallback, // propertiesCallback
  159. 0, // toS3Callback
  160. 0, // toS3CallbackTotalSize
  161. &dataCallback, // fromS3Callback
  162. &completeCallback, // completeCallback
  163. data, // callbackData
  164. timeoutMs // timeoutMs
  165. };
  166. // Perform the request
  167. request_perform(&params, requestContext);
  168. }