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