1 /** **************************************************************************
4 * Copyright 2008 Bryan Ischo <bryan@ischo.com>
6 * This file is part of libs3.
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.
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.
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
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/>.
25 ************************************************************************** **/
33 // put object ----------------------------------------------------------------
35 void S3_put_object(const S3BucketContext *bucketContext, const char *key,
36 uint64_t contentLength,
37 const S3PutProperties *putProperties,
38 S3RequestContext *requestContext,
39 const S3PutObjectHandler *handler, void *callbackData)
41 // Set up the RequestParams
42 RequestParams params =
44 HttpRequestTypePUT, // httpRequestType
45 { bucketContext->bucketName, // bucketName
46 bucketContext->protocol, // protocol
47 bucketContext->uriStyle, // uriStyle
48 bucketContext->accessKeyId, // accessKeyId
49 bucketContext->secretAccessKey }, // secretAccessKey
53 0, // copySourceBucketName
58 putProperties, // putProperties
59 handler->responseHandler.propertiesCallback, // propertiesCallback
60 handler->putObjectDataCallback, // toS3Callback
61 contentLength, // toS3CallbackTotalSize
63 handler->responseHandler.completeCallback, // completeCallback
64 callbackData // callbackData
67 // Perform the request
68 request_perform(¶ms, requestContext);
72 // copy object ---------------------------------------------------------------
75 typedef struct CopyObjectData
79 S3ResponsePropertiesCallback *responsePropertiesCallback;
80 S3ResponseCompleteCallback *responseCompleteCallback;
83 int64_t *lastModifiedReturn;
88 string_buffer(lastModified, 256);
92 static S3Status copyObjectXmlCallback(const char *elementPath,
93 const char *data, int dataLen,
96 CopyObjectData *coData = (CopyObjectData *) callbackData;
101 if (!strcmp(elementPath, "CopyObjectResult/LastModified")) {
102 string_buffer_append(coData->lastModified, data, dataLen, fit);
104 else if (!strcmp(elementPath, "CopyObjectResult/ETag")) {
105 if (coData->eTagReturnSize && coData->eTagReturn) {
106 coData->eTagReturnLen +=
107 snprintf(&(coData->eTagReturn[coData->eTagReturnLen]),
108 coData->eTagReturnSize -
109 coData->eTagReturnLen - 1,
110 "%.*s", dataLen, data);
111 if (coData->eTagReturnLen >= coData->eTagReturnSize) {
112 return S3StatusXmlParseFailure;
122 static S3Status copyObjectPropertiesCallback
123 (const S3ResponseProperties *responseProperties, void *callbackData)
125 CopyObjectData *coData = (CopyObjectData *) callbackData;
127 return (*(coData->responsePropertiesCallback))
128 (responseProperties, coData->callbackData);
132 static S3Status copyObjectDataCallback(int bufferSize, const char *buffer,
135 CopyObjectData *coData = (CopyObjectData *) callbackData;
137 return simplexml_add(&(coData->simpleXml), buffer, bufferSize);
141 static void copyObjectCompleteCallback(S3Status requestStatus,
142 const S3ErrorDetails *s3ErrorDetails,
145 CopyObjectData *coData = (CopyObjectData *) callbackData;
147 if (coData->lastModifiedReturn) {
148 time_t lastModified = -1;
149 if (coData->lastModifiedLen) {
150 lastModified = parseIso8601Time(coData->lastModified);
153 *(coData->lastModifiedReturn) = lastModified;
156 (*(coData->responseCompleteCallback))
157 (requestStatus, s3ErrorDetails, coData->callbackData);
159 simplexml_deinitialize(&(coData->simpleXml));
165 void S3_copy_object(const S3BucketContext *bucketContext, const char *key,
166 const char *destinationBucket, const char *destinationKey,
167 const S3PutProperties *putProperties,
168 int64_t *lastModifiedReturn, int eTagReturnSize,
169 char *eTagReturn, S3RequestContext *requestContext,
170 const S3ResponseHandler *handler, void *callbackData)
172 // Create the callback data
173 CopyObjectData *data =
174 (CopyObjectData *) malloc(sizeof(CopyObjectData));
176 (*(handler->completeCallback))(S3StatusOutOfMemory, 0, callbackData);
180 simplexml_initialize(&(data->simpleXml), ©ObjectXmlCallback, data);
182 data->responsePropertiesCallback = handler->propertiesCallback;
183 data->responseCompleteCallback = handler->completeCallback;
184 data->callbackData = callbackData;
186 data->lastModifiedReturn = lastModifiedReturn;
187 data->eTagReturnSize = eTagReturnSize;
188 data->eTagReturn = eTagReturn;
189 if (data->eTagReturnSize && data->eTagReturn) {
190 data->eTagReturn[0] = 0;
192 data->eTagReturnLen = 0;
193 string_buffer_initialize(data->lastModified);
195 // Set up the RequestParams
196 RequestParams params =
198 HttpRequestTypeCOPY, // httpRequestType
199 { destinationBucket ? destinationBucket :
200 bucketContext->bucketName, // bucketName
201 bucketContext->protocol, // protocol
202 bucketContext->uriStyle, // uriStyle
203 bucketContext->accessKeyId, // accessKeyId
204 bucketContext->secretAccessKey }, // secretAccessKey
205 destinationKey ? destinationKey : key, // key
208 bucketContext->bucketName, // copySourceBucketName
209 key, // copySourceKey
213 putProperties, // putProperties
214 ©ObjectPropertiesCallback, // propertiesCallback
216 0, // toS3CallbackTotalSize
217 ©ObjectDataCallback, // fromS3Callback
218 ©ObjectCompleteCallback, // completeCallback
222 // Perform the request
223 request_perform(¶ms, requestContext);
227 // get object ----------------------------------------------------------------
229 void S3_get_object(const S3BucketContext *bucketContext, const char *key,
230 const S3GetConditions *getConditions,
231 uint64_t startByte, uint64_t byteCount,
232 S3RequestContext *requestContext,
233 const S3GetObjectHandler *handler, void *callbackData)
235 // Set up the RequestParams
236 RequestParams params =
238 HttpRequestTypeGET, // httpRequestType
239 { bucketContext->bucketName, // bucketName
240 bucketContext->protocol, // protocol
241 bucketContext->uriStyle, // uriStyle
242 bucketContext->accessKeyId, // accessKeyId
243 bucketContext->secretAccessKey }, // secretAccessKey
247 0, // copySourceBucketName
249 getConditions, // getConditions
250 startByte, // startByte
251 byteCount, // byteCount
253 handler->responseHandler.propertiesCallback, // propertiesCallback
255 0, // toS3CallbackTotalSize
256 handler->getObjectDataCallback, // fromS3Callback
257 handler->responseHandler.completeCallback, // completeCallback
258 callbackData // callbackData
261 // Perform the request
262 request_perform(¶ms, requestContext);
266 // head object ---------------------------------------------------------------
268 void S3_head_object(const S3BucketContext *bucketContext, const char *key,
269 S3RequestContext *requestContext,
270 const S3ResponseHandler *handler, void *callbackData)
272 // Set up the RequestParams
273 RequestParams params =
275 HttpRequestTypeHEAD, // httpRequestType
276 { bucketContext->bucketName, // bucketName
277 bucketContext->protocol, // protocol
278 bucketContext->uriStyle, // uriStyle
279 bucketContext->accessKeyId, // accessKeyId
280 bucketContext->secretAccessKey }, // secretAccessKey
284 0, // copySourceBucketName
290 handler->propertiesCallback, // propertiesCallback
292 0, // toS3CallbackTotalSize
294 handler->completeCallback, // completeCallback
295 callbackData // callbackData
298 // Perform the request
299 request_perform(¶ms, requestContext);
303 // delete object --------------------------------------------------------------
305 void S3_delete_object(const S3BucketContext *bucketContext, const char *key,
306 S3RequestContext *requestContext,
307 const S3ResponseHandler *handler, void *callbackData)
309 // Set up the RequestParams
310 RequestParams params =
312 HttpRequestTypeDELETE, // httpRequestType
313 { bucketContext->bucketName, // bucketName
314 bucketContext->protocol, // protocol
315 bucketContext->uriStyle, // uriStyle
316 bucketContext->accessKeyId, // accessKeyId
317 bucketContext->secretAccessKey }, // secretAccessKey
321 0, // copySourceBucketName
327 handler->propertiesCallback, // propertiesCallback
329 0, // toS3CallbackTotalSize
331 handler->completeCallback, // completeCallback
332 callbackData // callbackData
335 // Perform the request
336 request_perform(¶ms, requestContext);