Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Classes / Pithos / ASIPithosObjectRequest.m @ 6b3a5e6a

History | View | Annotate | Download (101.6 kB)

1
//  ASIPithosObjectRequest.m
2
//  Based on ASICloudFilesObjectRequest.m
3
//
4
// Copyright 2011 GRNET S.A. All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or
7
// without modification, are permitted provided that the following
8
// conditions are met:
9
// 
10
//   1. Redistributions of source code must retain the above
11
//      copyright notice, this list of conditions and the following
12
//      disclaimer.
13
// 
14
//   2. Redistributions in binary form must reproduce the above
15
//      copyright notice, this list of conditions and the following
16
//      disclaimer in the documentation and/or other materials
17
//      provided with the distribution.
18
// 
19
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
20
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
23
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30
// POSSIBILITY OF SUCH DAMAGE.
31
// 
32
// The views and conclusions contained in the software and
33
// documentation are those of the authors and should not be
34
// interpreted as representing official policies, either expressed
35
// or implied, of GRNET S.A.
36

    
37
#import "ASIPithosObjectRequest.h"
38
#import "ASIPithosObject.h"
39

    
40
@interface ASIPithosObjectRequest (Private)
41
- (void)parseXMLData;
42
- (void)prepareObjectRequestWithETag:(NSString *)eTag 
43
                         contentType:(NSString *)contentType 
44
                     contentEncoding:(NSString *)contentEncoding 
45
                  contentDisposition:(NSString *)contentDisposition 
46
                            manifest:(NSString *)manifest 
47
                             sharing:(NSString *)sharing 
48
                            isPublic:(NSUInteger)isPublic 
49
                            metadata:(NSDictionary *)newMetadata;
50
@end
51

    
52
@implementation ASIPithosObjectRequest
53
@synthesize objectRequestType;
54
@synthesize containerName, objectName;
55
@synthesize currentObject;
56

    
57
#pragma mark -
58
#pragma mark Constructors
59

    
60
+ (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName objectName:(NSString *)objectName queryString:(NSString *)queryString {
61
    NSString *urlString = [NSString stringWithFormat:@"%@/%@/%@", 
62
                           [self storageURL], 
63
                           [containerName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], 
64
                           [objectName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
65
    if (queryString)
66
        urlString = [urlString stringByAppendingString:queryString];
67
    
68
	ASIPithosObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:urlString]] autorelease];
69
	[request setRequestMethod:method];
70
	[request addRequestHeader:@"X-Auth-Token" value:[self authToken]];
71
    request.containerName = containerName;
72
    request.objectName = objectName;
73
	return request;
74
}
75

    
76
+ (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName objectName:(NSString *)objectName {
77
	return [self storageRequestWithMethod:method containerName:containerName objectName:(NSString *)objectName queryString:nil];
78
}
79

    
80
#pragma mark -
81
#pragma mark Memory Management
82

    
83
- (void)dealloc {
84
    [currentObject release];
85
    [versions release];
86
    [hashes release];
87
    [blockHash release];
88
    [objectName release];
89
    [containerName release];
90
	[super dealloc];
91
}
92

    
93
#pragma mark -
94
#pragma mark Internal
95

    
96
- (void)parseXMLData {
97
    if (objectRequestType == ASIPithosObjectRequestHashmap) {
98
        hashes = [[NSMutableArray alloc] init];
99
    } else if (objectRequestType == ASIPithosObjectRequestVersions) {
100
        versions = [[NSMutableArray alloc] init];
101
    }
102
    
103
    NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease];
104
    [parser setDelegate:self];
105
    [parser setShouldProcessNamespaces:NO];
106
    [parser setShouldReportNamespacePrefixes:NO];
107
    [parser setShouldResolveExternalEntities:NO];
108
    [parser parse];
109
}
110

    
111
- (void)prepareObjectRequestWithETag:(NSString *)eTag 
112
                         contentType:(NSString *)contentType 
113
                     contentEncoding:(NSString *)contentEncoding 
114
                  contentDisposition:(NSString *)contentDisposition 
115
                            manifest:(NSString *)manifest 
116
                             sharing:(NSString *)sharing 
117
                            isPublic:(NSUInteger)isPublic 
118
                            metadata:(NSDictionary *)newMetadata {
119
    if (eTag)
120
        [self addRequestHeader:@"ETag" value:eTag];
121
    if (contentType)
122
        [self addRequestHeader:@"Content-Type" value:contentType];
123
    if (contentEncoding)
124
        [self addRequestHeader:@"Content-Encoding" value:contentEncoding];
125
    if (contentDisposition)
126
        [self addRequestHeader:@"Content-Disposition" value:contentDisposition];
127
    if (manifest)
128
        [self addRequestHeader:@"X-Object-Manifest" 
129
                         value:[manifest stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
130
    if (sharing)
131
        [self addRequestHeader:@"X-Object-Sharing" 
132
                         value:[sharing stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
133
    if (isPublic == ASIPithosObjectRequestPublicTrue) {
134
        [self addRequestHeader:@"X-Object-Public" value:@"true"];
135
    } else if (isPublic == ASIPithosObjectRequestPublicFalse) {
136
        [self addRequestHeader:@"X-Object-Public" value:@"false"];
137
    }
138
    
139
    if (newMetadata) {
140
        for (NSString *key in [newMetadata keyEnumerator]) {
141
            [self addRequestHeader:[[NSString stringWithFormat:@"X-Object-Meta-%@", key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] 
142
                             value:[[newMetadata objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
143
        }
144
    }
145
}
146

    
147
#pragma mark -
148
#pragma mark HEAD
149

    
150
// HEAD storageURL/container/object
151
+ (id)objectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
152
    return [self storageRequestWithMethod:@"HEAD" containerName:containerName objectName:objectName];
153
}
154

    
155
// HEAD storageURL/container/object?[version=version]
156
+ (id)objectMetadataRequestWithContainerName:(NSString *)containerName  objectName:(NSString *)objectName version:(NSString *)version {
157
    NSString *queryString = nil;
158
    if (version)
159
        queryString = [NSString stringWithFormat:@"?version=%@", version];
160
	return [self storageRequestWithMethod:@"HEAD" containerName:containerName objectName:objectName queryString:queryString];
161
}
162

    
163
// HEAD storageURL/container/object?[version=version] [If-Match]
164
+ (id)objectMetadataRequestWithContainerName:(NSString *)containerName  objectName:(NSString *)objectName 
165
                                     version:(NSString *)version 
166
                                     ifMatch:(NSString *)matchETag {
167
    ASIPithosObjectRequest *request = [self objectMetadataRequestWithContainerName:containerName objectName:objectName version:version];
168
    [request addRequestIfMatchHeader:matchETag];
169
    return request;
170
}
171

    
172
// HEAD storageURL/container/object?[version=version] [If-None-Match]
173
+ (id)objectMetadataRequestWithContainerName:(NSString *)containerName  objectName:(NSString *)objectName 
174
                                     version:(NSString *)version 
175
                                 ifNoneMatch:(NSString *)matchETag {
176
    ASIPithosObjectRequest *request = [self objectMetadataRequestWithContainerName:containerName objectName:objectName version:version];
177
    [request addRequestIfNoneMatchHeader:matchETag];
178
    return request;
179
}
180

    
181
// HEAD storageURL/container/object?[version=version] [If-Modified-Since]
182
+ (id)objectMetadataRequestWithContainerName:(NSString *)containerName  objectName:(NSString *)objectName 
183
                                     version:(NSString *)version 
184
                             ifModifiedSince:(NSDate *)sinceTimestamp {
185
    ASIPithosObjectRequest *request = [self objectMetadataRequestWithContainerName:containerName objectName:objectName version:version];
186
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
187
    return request;
188
}
189

    
190
// HEAD storageURL/container/object?[version=version] [If-Unmodified-Since]
191
+ (id)objectMetadataRequestWithContainerName:(NSString *)containerName  objectName:(NSString *)objectName 
192
                                     version:(NSString *)version 
193
                           ifUnmodifiedSince:(NSDate *)sinceTimestamp {
194
    ASIPithosObjectRequest *request = [self objectMetadataRequestWithContainerName:containerName objectName:objectName version:version];
195
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
196
    return request;
197
}
198

    
199
- (NSString *)eTag {
200
    // Etag, instead of ETag, because CFNetwork changes it
201
    // http://groups.google.com/group/asihttprequest/browse_thread/thread/7119f1a0ccf26fdf
202
	return [[self responseHeaders] objectForKey:@"Etag"];
203
}
204

    
205
- (NSUInteger)objectContentLength {
206
    NSString *objectContentLengthString = [[self responseHeaders] objectForKey:@"Content-Length"];
207
    if (objectContentLengthString)
208
        return [objectContentLengthString intValue];
209
    return 0;
210
}
211

    
212
- (NSString *)contentType {
213
	return [[self responseHeaders] objectForKey:@"Content-Type"];
214
}
215

    
216
- (NSDate *)lastModified {
217
    NSString *lastModifiedString = [[self responseHeaders] objectForKey:@"Last-Modified"];
218
    if (lastModifiedString)
219
        return [[self dateFormatterWithFormatId:1] dateFromString:lastModifiedString];
220
    return nil;
221
}
222

    
223
- (NSString *)contentEncoding {
224
	return [[self responseHeaders] objectForKey:@"Content-Encoding"];
225
}
226

    
227
- (NSString *)contentDisposition {
228
	return [[self responseHeaders] objectForKey:@"Content-Disposition"];
229
}
230

    
231
- (NSString *)version {
232
	return [[self responseHeaders] objectForKey:@"X-Object-Version"];
233
}
234

    
235
- (NSDate *)versionTimestamp {
236
    NSString *versionTimestampString = [[self responseHeaders] objectForKey:@"X-Object-Version-Timestamp"];
237
    if (versionTimestampString)
238
        return [[self dateFormatterWithFormatId:1] dateFromString:versionTimestampString];
239
    return nil;
240
}
241

    
242
- (NSString *)modifiedBy {
243
	return [[self responseHeaders] objectForKey:@"X-Object-Modified-By"];
244
}
245

    
246
- (NSString *)manifest {
247
	return [[[self responseHeaders] objectForKey:@"X-Object-Manifest"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
248
}
249

    
250
- (NSString *)sharing {
251
	return [[[self responseHeaders] objectForKey:@"X-Object-Sharing"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
252
}
253

    
254
- (NSString *)sharedBy {
255
	return [[[self responseHeaders] objectForKey:@"X-Object-Shared-By"] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
256
}
257

    
258
- (NSString *)publicURI {
259
	return [[self responseHeaders] objectForKey:@"X-Object-Public"];
260
}
261

    
262
- (NSDictionary *)metadata {
263
    if (metadata == nil) {
264
        metadata = [self getHeadersDictionaryForPrefix:@"X-Object-Meta-"];
265
        [metadata retain];
266
    }
267
    return metadata;
268
}
269

    
270
- (NSString *)allowedTo {
271
    return [[self responseHeaders] objectForKey:@"X-Object-Allowed-To"];
272
}
273

    
274
- (ASIPithosObject *)object {
275
    ASIPithosObject *object = [ASIPithosObject object];
276
    object.name = objectName;
277
    object.hash = [self eTag];
278
    object.contentType = [self contentType];
279
    object.contentEncoding = [self contentEncoding];
280
    object.contentDisposition = [self contentDisposition];
281
    object.lastModified = [self lastModified];
282
    object.version = [self version];
283
    object.versionTimestamp = [self versionTimestamp];
284
    object.modifiedBy = [self modifiedBy];
285
    object.manifest = [self manifest];
286
    object.sharing = [self sharing];
287
    object.sharedBy = [self sharedBy];
288
    object.publicURI = [self publicURI];
289
    object.metadata = (NSMutableDictionary *)[self metadata];
290
    object.allowedTo = [self allowedTo];
291
    
292
    if (objectRequestType == ASIPithosObjectRequestData) {
293
        object.bytes = [self objectContentLength];
294
        object.data = [self responseData];
295
    } else if (objectRequestType == ASIPithosObjectRequestHashmap) {
296
        object.bytes = [self bytes];
297
    }
298
    
299
    return object;
300
}
301

    
302
#pragma mark -
303
#pragma mark GET
304

    
305
// GET storageURL/container/object
306
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
307
    return [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName];
308
}
309

    
310
// GET storageURL/container/object?[version=version]
311
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName version:(NSString *)version {
312
    NSString *queryString = nil;
313
    if (version)
314
        queryString = [NSString stringWithFormat:@"?version=%@", version];
315
	return [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:queryString];
316
}
317

    
318
// GET storageURL/container/object?[version=version] [If-Match]
319
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
320
                                 version:(NSString *)version 
321
                                 ifMatch:(NSString *)matchETag {
322
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
323
    [request addRequestIfMatchHeader:matchETag];
324
    return request;
325
}
326

    
327
// GET storageURL/container/object?[version=version] [If-None-Match]
328
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
329
                                 version:(NSString *)version 
330
                             ifNoneMatch:(NSString *)matchETag {
331
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
332
    [request addRequestIfNoneMatchHeader:matchETag];
333
    return request;
334
}
335

    
336
// GET storageURL/container/object?[version=version] [If-Modified-Since]
337
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
338
                                 version:(NSString *)version 
339
                         ifModifiedSince:(NSDate *)sinceTimestamp {
340
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
341
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
342
    return request;
343
}
344

    
345
// GET storageURL/container/object?[version=version] [If-Unmodified-Since]
346
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
347
                                 version:(NSString *)version 
348
                       ifUnmodifiedSince:(NSDate *)sinceTimestamp {
349
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
350
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
351
    return request;
352
}
353

    
354
// GET storageURL/container/object?[version=version] [Range [If-Range]]
355
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
356
                                 version:(NSString *)version 
357
                                   range:(NSString *)rangeString {
358
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
359
    [request addRequestRangeHeader:rangeString];
360
    return request;
361
}
362

    
363
// GET storageURL/container/object?[version=version] [Range [If-Range]]
364
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
365
                                 version:(NSString *)version 
366
                                   range:(NSString *)rangeString 
367
                             ifRangeETag:(NSString *)rangeETag {
368
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
369
    [request addRequestRangeHeader:rangeString ifRangeETag:rangeETag];
370
    return request;
371
}
372

    
373
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
374
                                 version:(NSString *)version 
375
                                   range:(NSString *)rangeString 
376
                        ifRangeTimestamp:(NSDate *)rangeTimestamp {
377
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
378
    [request addRequestRangeHeader:rangeString ifRangeTimestamp:rangeTimestamp];
379
    return request;
380
}
381

    
382
// GET storageURL/container/object?[version=version] [Range] [If-Match]
383
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
384
                                 version:(NSString *)version 
385
                                   range:(NSString *)rangeString 
386
                                 ifMatch:(NSString *)matchETag {
387
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
388
    [request addRequestRangeHeader:rangeString];
389
    [request addRequestIfMatchHeader:matchETag];
390
    return request;    
391
}
392

    
393
// GET storageURL/container/object?[version=version] [Range] [If-None-Match]
394
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
395
                                 version:(NSString *)version 
396
                                   range:(NSString *)rangeString 
397
                             ifNoneMatch:(NSString *)matchETag {
398
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
399
    [request addRequestRangeHeader:rangeString];
400
    [request addRequestIfNoneMatchHeader:matchETag];
401
    return request;
402
}
403

    
404
- (NSData *)data {
405
    return [self responseData];
406
}
407

    
408
// GET storageURL/container/object?format=xml&hashmap=
409
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
410
    ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:@"?format=xml&hashmap="];
411
    request.objectRequestType = ASIPithosObjectRequestHashmap;
412
    return request;
413
}
414

    
415
// GET storageURL/container/object?format=xml&hashmap=[&version=version]
416
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName version:(NSString *)version {
417
    NSString *queryString = @"?format=xml&hashmap=";
418
    if (version)
419
        queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&version=%@", version]];
420
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:queryString];
421
    request.objectRequestType = ASIPithosObjectRequestHashmap;
422
    return request;
423
}
424

    
425
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-Match]
426
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
427
                                    version:(NSString *)version 
428
                                    ifMatch:(NSString *)matchETag {
429
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
430
    [request addRequestIfMatchHeader:matchETag];
431
    return request;
432
}
433

    
434
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-NoneMatch]
435
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
436
                                    version:(NSString *)version 
437
                                ifNoneMatch:(NSString *)matchETag {
438
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
439
    [request addRequestIfNoneMatchHeader:matchETag];
440
    return request;
441
}
442

    
443
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-Modified-Since]
444
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
445
                                    version:(NSString *)version 
446
                            ifModifiedSince:(NSDate *)sinceTimestamp {
447
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
448
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
449
    return request;
450
}
451

    
452
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-Unmodified-Since]
453
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
454
                                    version:(NSString *)version 
455
                          ifUnmodifiedSince:(NSDate *)sinceTimestamp {
456
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
457
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
458
    return request;
459
}
460

    
461
- (NSUInteger)blockSize {
462
    if (hashes == nil)
463
        [self parseXMLData];
464
    return blockSize;
465
}
466

    
467
- (NSString *)blockHash {
468
    if (hashes == nil)
469
        [self parseXMLData];
470
    return blockHash;
471
}
472

    
473
- (NSArray *)hashes {
474
    if (hashes == nil)
475
        [self parseXMLData];
476
    return hashes;
477
}
478

    
479
- (NSUInteger)bytes {
480
    if (hashes == nil)
481
        [self parseXMLData];
482
    return bytes;
483
}
484

    
485
// GET storageURL/container/object?format=xml&version=list
486
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
487
    ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:@"?format=xml&version=list"];
488
    request.objectRequestType = ASIPithosObjectRequestVersions;
489
    return request;
490
}
491

    
492
// GET storageURL/container/object?format=xml&version=list [If-Match]
493
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifMatch:(NSString *)matchETag {
494
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
495
    [request addRequestIfMatchHeader:matchETag];
496
    return request;
497
}
498

    
499
// GET storageURL/container/object?format=xml&version=list [If-None-Match]
500
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifNoneMatch:(NSString *)matchETag {
501
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
502
    [request addRequestIfNoneMatchHeader:matchETag];
503
    return request;
504
}
505

    
506
// GET storageURL/container/object?format=xml&version=list [If-Modified-Since]
507
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifModifiedSince:(NSDate *)sinceTimestamp {
508
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
509
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
510
    return request;
511
}
512

    
513
// GET storageURL/container/object?format=xml&version=list [If-Unmodified-Since]
514
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifUnmodifiedSince:(NSDate *)sinceTimestamp {
515
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
516
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
517
    return request;
518
}
519

    
520
- (NSArray *)versions {
521
    if (versions == nil)
522
        [self parseXMLData];
523
    return versions;
524
}
525

    
526
#pragma mark -
527
#pragma mark PUT, COPY, MOVE
528

    
529
// PUT storageURL/container/object (from ASIPithosObject with data)
530
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object {
531
    NSUInteger isPublic = ASIPithosObjectRequestPublicIgnore;
532
    if (object.publicURI) {
533
        isPublic = ASIPithosObjectRequestPublicTrue;
534
        if ([object.publicURI isEqualToString:@""])
535
            isPublic = ASIPithosObjectRequestPublicFalse;
536
    }
537
    return [self writeObjectDataRequestWithContainerName:containerName 
538
                                              objectName:object.name 
539
                                                    eTag:object.hash 
540
                                             contentType:object.contentType 
541
                                         contentEncoding:object.contentEncoding 
542
                                      contentDisposition:object.contentDisposition 
543
                                                manifest:object.manifest 
544
                                                 sharing:object.sharing 
545
                                                isPublic:isPublic
546
                                                metadata:object.metadata 
547
                                                    data:object.data];
548
}
549

    
550
// PUT storageURL/container/object (from ASIPithosObject with data) [If-Match]
551
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object ifMatch:(NSString *)matchETag {
552
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName object:object];
553
    [request addRequestIfMatchHeader:matchETag];
554
    return request;
555
}
556

    
557
// PUT storageURL/container/object (from ASIPithosObject with data) [If-None-Match]
558
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object ifNoneMatch:(NSString *)matchETag  {
559
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName object:object];
560
    [request addRequestIfNoneMatchHeader:matchETag];
561
    return request;
562
}
563

    
564
// PUT storageURL/container/object (from NSData)
565
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
566
                                   objectName:(NSString *)objectName 
567
                                         eTag:(NSString *)eTag 
568
                                  contentType:(NSString *)contentType 
569
                              contentEncoding:(NSString *)contentEncoding 
570
                           contentDisposition:(NSString *)contentDisposition 
571
                                     manifest:(NSString *)manifest 
572
                                      sharing:(NSString *)sharing 
573
                                     isPublic:(NSUInteger)isPublic 
574
                                     metadata:(NSDictionary *)metadata 
575
                                         data:(NSData *)data {
576
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
577
    [request prepareObjectRequestWithETag:eTag 
578
                              contentType:contentType 
579
                          contentEncoding:contentEncoding 
580
                       contentDisposition:contentDisposition 
581
                                 manifest:manifest 
582
                                  sharing:sharing 
583
                                 isPublic:isPublic 
584
                                 metadata:metadata];
585
	[request appendPostData:data];
586
    request.requestMethod = @"PUT";
587
	return request;
588
}
589

    
590
// PUT storageURL/container/object (from NSData) [If-Match]
591
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
592
                                   objectName:(NSString *)objectName 
593
                                         eTag:(NSString *)eTag 
594
                                  contentType:(NSString *)contentType 
595
                              contentEncoding:(NSString *)contentEncoding 
596
                           contentDisposition:(NSString *)contentDisposition 
597
                                     manifest:(NSString *)manifest 
598
                                      sharing:(NSString *)sharing 
599
                                     isPublic:(NSUInteger)isPublic 
600
                                     metadata:(NSDictionary *)metadata 
601
                                         data:(NSData *)data 
602
                                      ifMatch:(NSString *)matchETag {
603
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
604
                                                                               eTag:eTag 
605
                                                                        contentType:contentType 
606
                                                                    contentEncoding:contentEncoding 
607
                                                                 contentDisposition:contentDisposition 
608
                                                                           manifest:manifest 
609
                                                                            sharing:sharing 
610
                                                                           isPublic:isPublic 
611
                                                                           metadata:metadata 
612
                                                                               data:data];
613
    [request addRequestIfMatchHeader:matchETag];
614
    return request;                                                                          
615
}
616

    
617
// PUT storageURL/container/object (from NSData) [If-None-Match]
618
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
619
                                   objectName:(NSString *)objectName 
620
                                         eTag:(NSString *)eTag 
621
                                  contentType:(NSString *)contentType 
622
                              contentEncoding:(NSString *)contentEncoding 
623
                           contentDisposition:(NSString *)contentDisposition 
624
                                     manifest:(NSString *)manifest 
625
                                      sharing:(NSString *)sharing 
626
                                     isPublic:(NSUInteger)isPublic 
627
                                     metadata:(NSDictionary *)metadata 
628
                                         data:(NSData *)data 
629
                                  ifNoneMatch:(NSString *)matchETag {
630
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
631
                                                                               eTag:eTag 
632
                                                                        contentType:contentType 
633
                                                                    contentEncoding:contentEncoding 
634
                                                                 contentDisposition:contentDisposition 
635
                                                                           manifest:manifest 
636
                                                                            sharing:sharing 
637
                                                                           isPublic:isPublic 
638
                                                                           metadata:metadata 
639
                                                                               data:data];
640
    [request addRequestIfNoneMatchHeader:matchETag];
641
    return request;                                                                          
642
}
643

    
644
// PUT storageURL/container/object (from file)
645
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
646
                                   objectName:(NSString *)objectName 
647
                                         eTag:(NSString *)eTag 
648
                                  contentType:(NSString *)contentType 
649
                              contentEncoding:(NSString *)contentEncoding 
650
                           contentDisposition:(NSString *)contentDisposition 
651
                                     manifest:(NSString *)manifest 
652
                                      sharing:(NSString *)sharing 
653
                                     isPublic:(NSUInteger)isPublic 
654
                                     metadata:(NSDictionary *)metadata 
655
                                         file:(NSString *)filePath {
656
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
657
    [request prepareObjectRequestWithETag:eTag 
658
                              contentType:contentType 
659
                          contentEncoding:contentEncoding 
660
                       contentDisposition:contentDisposition 
661
                                 manifest:manifest 
662
                                  sharing:sharing 
663
                                 isPublic:isPublic 
664
                                 metadata:metadata];
665
	request.shouldStreamPostDataFromDisk = YES;
666
    request.postBodyFilePath = filePath;
667
    request.requestMethod = @"PUT";
668
	return request;    
669
}
670

    
671
// PUT storageURL/container/object (from file) [If-Match]
672
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
673
                                   objectName:(NSString *)objectName 
674
                                         eTag:(NSString *)eTag 
675
                                  contentType:(NSString *)contentType 
676
                              contentEncoding:(NSString *)contentEncoding 
677
                           contentDisposition:(NSString *)contentDisposition 
678
                                     manifest:(NSString *)manifest 
679
                                      sharing:(NSString *)sharing 
680
                                     isPublic:(NSUInteger)isPublic 
681
                                     metadata:(NSDictionary *)metadata 
682
                                         file:(NSString *)filePath 
683
                                      ifMatch:(NSString *)matchETag {
684
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
685
                                                                               eTag:eTag 
686
                                                                        contentType:contentType 
687
                                                                    contentEncoding:contentEncoding 
688
                                                                 contentDisposition:contentDisposition 
689
                                                                           manifest:manifest 
690
                                                                            sharing:sharing 
691
                                                                           isPublic:isPublic 
692
                                                                           metadata:metadata 
693
                                                                               file:filePath];
694
    [request addRequestIfMatchHeader:matchETag];
695
    return request;                                                                          
696
}
697

    
698
// PUT storageURL/container/object (from file) [If-None-Match]
699
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
700
                                   objectName:(NSString *)objectName 
701
                                         eTag:(NSString *)eTag 
702
                                  contentType:(NSString *)contentType 
703
                              contentEncoding:(NSString *)contentEncoding 
704
                           contentDisposition:(NSString *)contentDisposition 
705
                                     manifest:(NSString *)manifest 
706
                                      sharing:(NSString *)sharing 
707
                                     isPublic:(NSUInteger)isPublic 
708
                                     metadata:(NSDictionary *)metadata 
709
                                         file:(NSString *)filePath 
710
                                  ifNoneMatch:(NSString *)matchETag {
711
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
712
                                                                               eTag:eTag 
713
                                                                        contentType:contentType 
714
                                                                    contentEncoding:contentEncoding 
715
                                                                 contentDisposition:contentDisposition 
716
                                                                           manifest:manifest 
717
                                                                            sharing:sharing 
718
                                                                           isPublic:isPublic 
719
                                                                           metadata:metadata 
720
                                                                               file:filePath];
721
    [request addRequestIfNoneMatchHeader:matchETag];
722
    return request;                                                                          
723
}
724

    
725
// PUT storageURL/container/object (from hashes)
726
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
727
                                   objectName:(NSString *)objectName 
728
                                  contentType:(NSString *)contentType 
729
                              contentEncoding:(NSString *)contentEncoding 
730
                           contentDisposition:(NSString *)contentDisposition 
731
                                     manifest:(NSString *)manifest 
732
                                      sharing:(NSString *)sharing 
733
                                     isPublic:(NSUInteger)isPublic 
734
                                     metadata:(NSDictionary *)metadata 
735
                                    blockSize:(NSUInteger)blockSize 
736
                                    blockHash:(NSString *)blockHash 
737
                                       hashes:(NSArray *)hashes 
738
                                        bytes:(NSUInteger)bytes {
739
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName queryString:@"?format=xml&hashmap="];
740
    [request prepareObjectRequestWithETag:nil 
741
                              contentType:contentType 
742
                          contentEncoding:contentEncoding 
743
                       contentDisposition:contentDisposition 
744
                                 manifest:manifest 
745
                                  sharing:sharing 
746
                                 isPublic:isPublic 
747
                                 metadata:metadata];
748
    NSString *dataString = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?><object name=\"%@\" bytes=\"%lu\" block_size=\"%lu\" block_hash=\"%@\">", 
749
                            [(NSString *)CFXMLCreateStringByEscapingEntities(NULL, (CFStringRef)objectName , NULL) autorelease], 
750
                            bytes, blockSize, blockHash];
751
    for (NSString *hash in hashes) {
752
        dataString = [dataString stringByAppendingFormat:@"<hash>%@</hash>", hash];
753
    }
754
    dataString = [dataString stringByAppendingString:@"</object>"];
755
	[request appendPostData:[dataString dataUsingEncoding:NSUTF8StringEncoding]];
756
    request.requestMethod = @"PUT";
757
	return request;    
758
}
759

    
760
// PUT storageURL/container/object (from hashes) [If-Match]
761
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
762
                                   objectName:(NSString *)objectName 
763
                                  contentType:(NSString *)contentType 
764
                              contentEncoding:(NSString *)contentEncoding 
765
                           contentDisposition:(NSString *)contentDisposition 
766
                                     manifest:(NSString *)manifest 
767
                                      sharing:(NSString *)sharing 
768
                                     isPublic:(NSUInteger)isPublic 
769
                                     metadata:(NSDictionary *)metadata 
770
                                    blockSize:(NSUInteger)blockSize 
771
                                    blockHash:(NSString *)blockHash 
772
                                       hashes:(NSArray *)hashes 
773
                                        bytes:(NSUInteger)bytes 
774
                                      ifMatch:(NSString *)matchETag {
775
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
776
                                                                        contentType:contentType 
777
                                                                    contentEncoding:contentEncoding 
778
                                                                 contentDisposition:contentDisposition 
779
                                                                           manifest:manifest 
780
                                                                            sharing:sharing 
781
                                                                           isPublic:isPublic 
782
                                                                           metadata:metadata 
783
                                                                          blockSize:blockSize 
784
                                                                          blockHash:blockHash 
785
                                                                             hashes:hashes 
786
                                                                              bytes:bytes];
787
    [request addRequestIfMatchHeader:matchETag];
788
    return request;                                                                          
789
}
790

    
791
// PUT storageURL/container/object (from hashes) [If-None-Match]
792
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
793
                                   objectName:(NSString *)objectName 
794
                                  contentType:(NSString *)contentType 
795
                              contentEncoding:(NSString *)contentEncoding 
796
                           contentDisposition:(NSString *)contentDisposition 
797
                                     manifest:(NSString *)manifest 
798
                                      sharing:(NSString *)sharing 
799
                                     isPublic:(NSUInteger)isPublic 
800
                                     metadata:(NSDictionary *)metadata 
801
                                    blockSize:(NSUInteger)blockSize 
802
                                    blockHash:(NSString *)blockHash 
803
                                       hashes:(NSArray *)hashes 
804
                                        bytes:(NSUInteger)bytes 
805
                                  ifNoneMatch:(NSString *)matchETag {
806
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
807
                                                                        contentType:contentType 
808
                                                                    contentEncoding:contentEncoding 
809
                                                                 contentDisposition:contentDisposition 
810
                                                                           manifest:manifest 
811
                                                                            sharing:sharing 
812
                                                                           isPublic:isPublic 
813
                                                                           metadata:metadata 
814
                                                                          blockSize:blockSize 
815
                                                                          blockHash:blockHash 
816
                                                                             hashes:hashes 
817
                                                                              bytes:bytes];
818
    [request addRequestIfNoneMatchHeader:matchETag];
819
    return request;                                                                          
820
}
821

    
822
// PUT storageURL/container/object (copy from source)
823
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
824
                                  objectName:(NSString *)objectName 
825
                                 contentType:(NSString *)contentType 
826
                             contentEncoding:(NSString *)contentEncoding 
827
                          contentDisposition:(NSString *)contentDisposition 
828
                                    manifest:(NSString *)manifest 
829
                                     sharing:(NSString *)sharing 
830
                                    isPublic:(NSUInteger)isPublic 
831
                                    metadata:(NSDictionary *)metadata 
832
                         sourceContainerName:(NSString *)sourceContainerName 
833
                            sourceObjectName:(NSString *)sourceObjectName
834
                               sourceAccount:(NSString *)sourceAccount
835
                               sourceVersion:(NSString *)sourceVersion {
836
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
837
    [request prepareObjectRequestWithETag:nil 
838
                              contentType:contentType 
839
                          contentEncoding:contentEncoding 
840
                       contentDisposition:contentDisposition 
841
                                 manifest:manifest 
842
                                  sharing:sharing 
843
                                 isPublic:isPublic 
844
                                 metadata:metadata];
845
    [request addRequestHeader:@"Content-Length" value:@"0"];
846
    [request addRequestHeader:@"X-Copy-From" 
847
                        value:[[NSString stringWithFormat:@"/%@/%@", sourceContainerName, sourceObjectName] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
848
    if (sourceAccount)
849
        [request addRequestHeader:@"X-Source-Account" 
850
                            value:[sourceAccount stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
851
    if (sourceVersion)
852
        [request addRequestHeader:@"X-Source-Version" value:sourceVersion];
853
    return request;
854
}
855

    
856
// PUT storageURL/container/object (copy from source) [If-Match]
857
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
858
                                  objectName:(NSString *)objectName 
859
                                 contentType:(NSString *)contentType 
860
                             contentEncoding:(NSString *)contentEncoding 
861
                          contentDisposition:(NSString *)contentDisposition 
862
                                    manifest:(NSString *)manifest 
863
                                     sharing:(NSString *)sharing 
864
                                    isPublic:(NSUInteger)isPublic 
865
                                    metadata:(NSDictionary *)metadata 
866
                         sourceContainerName:(NSString *)sourceContainerName 
867
                            sourceObjectName:(NSString *)sourceObjectName
868
                               sourceAccount:(NSString *)sourceAccount
869
                               sourceVersion:(NSString *)sourceVersion 
870
                                     ifMatch:(NSString *)matchETag {
871
    ASIPithosObjectRequest *request = [self copyObjectDataRequestWithContainerName:containerName objectName:objectName 
872
                                                                       contentType:contentType 
873
                                                                   contentEncoding:contentEncoding 
874
                                                                contentDisposition:contentDisposition 
875
                                                                          manifest:manifest 
876
                                                                           sharing:sharing 
877
                                                                          isPublic:isPublic 
878
                                                                          metadata:metadata 
879
                                                               sourceContainerName:sourceContainerName 
880
                                                                  sourceObjectName:sourceObjectName 
881
                                                                     sourceAccount:sourceAccount
882
                                                                     sourceVersion:sourceVersion];
883
    [request addRequestIfMatchHeader:matchETag];
884
    return request;                                                                          
885
}
886

    
887
// PUT storageURL/container/object (copy from source) [If-None-Match]
888
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
889
                                  objectName:(NSString *)objectName 
890
                                 contentType:(NSString *)contentType 
891
                             contentEncoding:(NSString *)contentEncoding 
892
                          contentDisposition:(NSString *)contentDisposition 
893
                                    manifest:(NSString *)manifest 
894
                                     sharing:(NSString *)sharing 
895
                                    isPublic:(NSUInteger)isPublic 
896
                                    metadata:(NSDictionary *)metadata 
897
                         sourceContainerName:(NSString *)sourceContainerName 
898
                            sourceObjectName:(NSString *)sourceObjectName
899
                               sourceAccount:(NSString *)sourceAccount
900
                               sourceVersion:(NSString *)sourceVersion 
901
                                 ifNoneMatch:(NSString *)matchETag {
902
    ASIPithosObjectRequest *request = [self copyObjectDataRequestWithContainerName:containerName objectName:objectName 
903
                                                                       contentType:contentType 
904
                                                                   contentEncoding:contentEncoding 
905
                                                                contentDisposition:contentDisposition 
906
                                                                          manifest:manifest 
907
                                                                           sharing:sharing 
908
                                                                          isPublic:isPublic 
909
                                                                          metadata:metadata 
910
                                                               sourceContainerName:sourceContainerName 
911
                                                                  sourceObjectName:sourceObjectName 
912
                                                                     sourceAccount:sourceAccount
913
                                                                     sourceVersion:sourceVersion];
914
    [request addRequestIfNoneMatchHeader:matchETag];
915
    return request;                                                                          
916
}
917

    
918
// COPY storageURL/container/object (copy to destination)
919
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
920
                                  objectName:(NSString *)objectName 
921
                                 contentType:(NSString *)contentType 
922
                             contentEncoding:(NSString *)contentEncoding 
923
                          contentDisposition:(NSString *)contentDisposition 
924
                                    manifest:(NSString *)manifest 
925
                                     sharing:(NSString *)sharing 
926
                                    isPublic:(NSUInteger)isPublic 
927
                                    metadata:(NSDictionary *)metadata 
928
                    destinationContainerName:(NSString *)destinationContainerName 
929
                       destinationObjectName:(NSString *)destinationObjectName
930
                          destinationAccount:(NSString *)destinationAccount
931
                               sourceVersion:(NSString *)sourceVersion {
932
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"COPY" containerName:containerName objectName:objectName];
933
    [request prepareObjectRequestWithETag:nil 
934
                              contentType:contentType 
935
                          contentEncoding:contentEncoding 
936
                       contentDisposition:contentDisposition 
937
                                 manifest:manifest 
938
                                  sharing:sharing 
939
                                 isPublic:isPublic 
940
                                 metadata:metadata];
941
    [request addRequestHeader:@"Destination" 
942
                        value:[[NSString stringWithFormat:@"/%@/%@", destinationContainerName, destinationObjectName] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
943
    if (destinationAccount)
944
        [request addRequestHeader:@"Destination-Account" 
945
                            value:[destinationAccount stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
946
    if (sourceVersion)
947
        [request addRequestHeader:@"X-Source-Version" value:sourceVersion];
948
    return request;
949
}
950

    
951
// COPY storageURL/container/object (copy to destination) [If-Match]
952
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
953
                                  objectName:(NSString *)objectName 
954
                                 contentType:(NSString *)contentType 
955
                             contentEncoding:(NSString *)contentEncoding 
956
                          contentDisposition:(NSString *)contentDisposition 
957
                                    manifest:(NSString *)manifest 
958
                                     sharing:(NSString *)sharing 
959
                                    isPublic:(NSUInteger)isPublic 
960
                                    metadata:(NSDictionary *)metadata 
961
                    destinationContainerName:(NSString *)destinationContainerName 
962
                       destinationObjectName:(NSString *)destinationObjectName
963
                          destinationAccount:(NSString *)destinationAccount
964
                               sourceVersion:(NSString *)sourceVersion 
965
                                     ifMatch:(NSString *)matchETag {
966
    ASIPithosObjectRequest *request = [self copyObjectDataRequestWithContainerName:containerName objectName:objectName 
967
                                                                       contentType:contentType 
968
                                                                   contentEncoding:contentEncoding 
969
                                                                contentDisposition:contentDisposition 
970
                                                                          manifest:manifest 
971
                                                                           sharing:sharing 
972
                                                                          isPublic:isPublic 
973
                                                                          metadata:metadata 
974
                                                          destinationContainerName:destinationContainerName 
975
                                                             destinationObjectName:destinationObjectName 
976
                                                                destinationAccount:destinationAccount
977
                                                                     sourceVersion:sourceVersion];
978
    [request addRequestIfMatchHeader:matchETag];
979
    return request;                                                                          
980
}
981

    
982
// COPY storageURL/container/object (copy to destination) [If-None-Match]
983
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
984
                                  objectName:(NSString *)objectName 
985
                                 contentType:(NSString *)contentType 
986
                             contentEncoding:(NSString *)contentEncoding 
987
                          contentDisposition:(NSString *)contentDisposition 
988
                                    manifest:(NSString *)manifest 
989
                                     sharing:(NSString *)sharing 
990
                                    isPublic:(NSUInteger)isPublic 
991
                                    metadata:(NSDictionary *)metadata 
992
                    destinationContainerName:(NSString *)destinationContainerName 
993
                       destinationObjectName:(NSString *)destinationObjectName
994
                          destinationAccount:(NSString *)destinationAccount
995
                               sourceVersion:(NSString *)sourceVersion 
996
                                 ifNoneMatch:(NSString *)matchETag {
997
    ASIPithosObjectRequest *request = [self copyObjectDataRequestWithContainerName:containerName objectName:objectName 
998
                                                                       contentType:contentType 
999
                                                                   contentEncoding:contentEncoding 
1000
                                                                contentDisposition:contentDisposition 
1001
                                                                          manifest:manifest 
1002
                                                                           sharing:sharing 
1003
                                                                          isPublic:isPublic 
1004
                                                                          metadata:metadata 
1005
                                                          destinationContainerName:destinationContainerName 
1006
                                                             destinationObjectName:destinationObjectName 
1007
                                                                destinationAccount:destinationAccount
1008
                                                                     sourceVersion:sourceVersion];
1009
    [request addRequestIfNoneMatchHeader:matchETag];
1010
    return request;                                                                          
1011
}
1012

    
1013
// PUT storageURL/container/object (move from source)
1014
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1015
                                  objectName:(NSString *)objectName 
1016
                                 contentType:(NSString *)contentType 
1017
                             contentEncoding:(NSString *)contentEncoding 
1018
                          contentDisposition:(NSString *)contentDisposition 
1019
                                    manifest:(NSString *)manifest 
1020
                                     sharing:(NSString *)sharing 
1021
                                    isPublic:(NSUInteger)isPublic 
1022
                                    metadata:(NSDictionary *)metadata 
1023
                         sourceContainerName:(NSString *)sourceContainerName 
1024
                            sourceObjectName:(NSString *)sourceObjectName 
1025
                               sourceAccount:(NSString *)sourceAccount { 
1026
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
1027
    [request prepareObjectRequestWithETag:nil 
1028
                              contentType:contentType 
1029
                          contentEncoding:contentEncoding 
1030
                       contentDisposition:contentDisposition 
1031
                                 manifest:manifest 
1032
                                  sharing:sharing 
1033
                                 isPublic:isPublic 
1034
                                 metadata:metadata];
1035
    [request addRequestHeader:@"Content-Length" value:@"0"];
1036
    [request addRequestHeader:@"X-Move-From" 
1037
                        value:[[NSString stringWithFormat:@"/%@/%@", sourceContainerName, sourceObjectName] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
1038
    if (sourceAccount)
1039
        [request addRequestHeader:@"X-Source-Account" 
1040
                            value:[sourceAccount stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
1041
    return request;
1042
}
1043

    
1044
// PUT storageURL/container/object (move from source) [If-Match]
1045
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1046
                                  objectName:(NSString *)objectName 
1047
                                 contentType:(NSString *)contentType 
1048
                             contentEncoding:(NSString *)contentEncoding 
1049
                          contentDisposition:(NSString *)contentDisposition 
1050
                                    manifest:(NSString *)manifest 
1051
                                     sharing:(NSString *)sharing 
1052
                                    isPublic:(NSUInteger)isPublic 
1053
                                    metadata:(NSDictionary *)metadata 
1054
                         sourceContainerName:(NSString *)sourceContainerName 
1055
                            sourceObjectName:(NSString *)sourceObjectName
1056
                               sourceAccount:(NSString *)sourceAccount
1057
                                     ifMatch:(NSString *)matchETag {
1058
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1059
                                                                       contentType:contentType 
1060
                                                                   contentEncoding:contentEncoding 
1061
                                                                contentDisposition:contentDisposition 
1062
                                                                          manifest:manifest 
1063
                                                                           sharing:sharing 
1064
                                                                          isPublic:isPublic 
1065
                                                                          metadata:metadata 
1066
                                                               sourceContainerName:sourceContainerName 
1067
                                                                  sourceObjectName:sourceObjectName 
1068
                                                                     sourceAccount:sourceAccount];
1069
    [request addRequestIfMatchHeader:matchETag];
1070
    return request;                                               
1071
}
1072

    
1073
// PUT storageURL/container/object (move from source) [If-None-Match]
1074
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1075
                                  objectName:(NSString *)objectName 
1076
                                 contentType:(NSString *)contentType 
1077
                             contentEncoding:(NSString *)contentEncoding 
1078
                          contentDisposition:(NSString *)contentDisposition 
1079
                                    manifest:(NSString *)manifest 
1080
                                     sharing:(NSString *)sharing 
1081
                                    isPublic:(NSUInteger)isPublic 
1082
                                    metadata:(NSDictionary *)metadata 
1083
                         sourceContainerName:(NSString *)sourceContainerName 
1084
                            sourceObjectName:(NSString *)sourceObjectName
1085
                               sourceAccount:(NSString *)sourceAccount
1086
                                 ifNoneMatch:(NSString *)matchETag {
1087
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1088
                                                                       contentType:contentType 
1089
                                                                   contentEncoding:contentEncoding 
1090
                                                                contentDisposition:contentDisposition 
1091
                                                                          manifest:manifest 
1092
                                                                           sharing:sharing 
1093
                                                                          isPublic:isPublic 
1094
                                                                          metadata:metadata 
1095
                                                               sourceContainerName:sourceContainerName 
1096
                                                                  sourceObjectName:sourceObjectName 
1097
                                                                     sourceAccount:sourceAccount];
1098
    [request addRequestIfNoneMatchHeader:matchETag];
1099
    return request;                                               
1100
}
1101

    
1102
// MOVE storageURL/container/object (move to destination)
1103
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1104
                                  objectName:(NSString *)objectName 
1105
                                 contentType:(NSString *)contentType 
1106
                             contentEncoding:(NSString *)contentEncoding 
1107
                          contentDisposition:(NSString *)contentDisposition 
1108
                                    manifest:(NSString *)manifest 
1109
                                     sharing:(NSString *)sharing 
1110
                                    isPublic:(NSUInteger)isPublic 
1111
                                    metadata:(NSDictionary *)metadata 
1112
                    destinationContainerName:(NSString *)destinationContainerName 
1113
                       destinationObjectName:(NSString *)destinationObjectName 
1114
                          destinationAccount:(NSString *)destinationAccount {
1115
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"MOVE" containerName:containerName objectName:objectName];
1116
    [request prepareObjectRequestWithETag:nil 
1117
                              contentType:contentType 
1118
                          contentEncoding:contentEncoding 
1119
                       contentDisposition:contentDisposition 
1120
                                 manifest:manifest 
1121
                                  sharing:sharing 
1122
                                 isPublic:isPublic 
1123
                                 metadata:metadata];
1124
    [request addRequestHeader:@"Destination" 
1125
                        value:[[NSString stringWithFormat:@"/%@/%@", destinationContainerName, destinationObjectName] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
1126
    if (destinationAccount)
1127
        [request addRequestHeader:@"Destination-Account" 
1128
                            value:[destinationAccount stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
1129
    return request;
1130
}
1131

    
1132
// MOVE storageURL/container/object (move to destination) [If-Match]
1133
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1134
                                  objectName:(NSString *)objectName 
1135
                                 contentType:(NSString *)contentType 
1136
                             contentEncoding:(NSString *)contentEncoding 
1137
                          contentDisposition:(NSString *)contentDisposition 
1138
                                    manifest:(NSString *)manifest 
1139
                                     sharing:(NSString *)sharing 
1140
                                    isPublic:(NSUInteger)isPublic 
1141
                                    metadata:(NSDictionary *)metadata 
1142
                    destinationContainerName:(NSString *)destinationContainerName 
1143
                       destinationObjectName:(NSString *)destinationObjectName
1144
                          destinationAccount:(NSString *)destinationAccount
1145
                                     ifMatch:(NSString *)matchETag {
1146
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1147
                                                                       contentType:contentType 
1148
                                                                   contentEncoding:contentEncoding 
1149
                                                                contentDisposition:contentDisposition 
1150
                                                                          manifest:manifest 
1151
                                                                           sharing:sharing 
1152
                                                                          isPublic:isPublic 
1153
                                                                          metadata:metadata 
1154
                                                          destinationContainerName:destinationContainerName 
1155
                                                             destinationObjectName:destinationObjectName 
1156
                                                                destinationAccount:destinationAccount];
1157
    [request addRequestIfMatchHeader:matchETag];
1158
    return request;                                                                          
1159
}
1160

    
1161
// MOVE storageURL/container/object (move to destination) [If-None-Match]
1162
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1163
                                  objectName:(NSString *)objectName 
1164
                                 contentType:(NSString *)contentType 
1165
                             contentEncoding:(NSString *)contentEncoding 
1166
                          contentDisposition:(NSString *)contentDisposition 
1167
                                    manifest:(NSString *)manifest 
1168
                                     sharing:(NSString *)sharing 
1169
                                    isPublic:(NSUInteger)isPublic 
1170
                                    metadata:(NSDictionary *)metadata 
1171
                    destinationContainerName:(NSString *)destinationContainerName 
1172
                       destinationObjectName:(NSString *)destinationObjectName
1173
                          destinationAccount:(NSString *)destinationAccount
1174
                                 ifNoneMatch:(NSString *)matchETag {
1175
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1176
                                                                       contentType:contentType 
1177
                                                                   contentEncoding:contentEncoding 
1178
                                                                contentDisposition:contentDisposition 
1179
                                                                          manifest:manifest 
1180
                                                                           sharing:sharing 
1181
                                                                          isPublic:isPublic 
1182
                                                                          metadata:metadata 
1183
                                                          destinationContainerName:destinationContainerName 
1184
                                                             destinationObjectName:destinationObjectName 
1185
                                                                destinationAccount:destinationAccount];
1186
    [request addRequestIfNoneMatchHeader:matchETag];
1187
    return request;                                                                          
1188
}
1189

    
1190
#pragma mark -
1191
#pragma mark POST
1192

    
1193
// POST storageURL/container/object?[update=] (update metadata)
1194
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName update:(BOOL)update {
1195
    NSString *queryString = nil;
1196
    if (update)
1197
        queryString = @"?update=";
1198
	return [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1199
}
1200

    
1201
// POST storageURL/container/object?[update=] (update metadata) [If-Match]
1202
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1203
                                            update:(BOOL)update 
1204
                                           ifMatch:(NSString *)matchETag {
1205
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName update:update];
1206
    [request addRequestIfMatchHeader:matchETag];
1207
    return request;                                                                          
1208
}
1209

    
1210
// POST storageURL/container/object?[update=] (update metadata) [If-None-Match]
1211
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1212
                                            update:(BOOL)update 
1213
                                       ifNoneMatch:(NSString *)matchETag {
1214
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName update:update];
1215
    [request addRequestIfNoneMatchHeader:matchETag];
1216
    return request;                                                                          
1217
}
1218

    
1219
// POST storageURL/container/object?[update=] (update metadata)
1220
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1221
                                   contentEncoding:(NSString *)contentEncoding 
1222
                                contentDisposition:(NSString *)contentDisposition 
1223
                                          manifest:(NSString *)manifest 
1224
                                           sharing:(NSString *)sharing 
1225
                                          isPublic:(NSUInteger)isPublic 
1226
                                          metadata:(NSDictionary *)metadata 
1227
                                            update:(BOOL)update {
1228
    NSString *queryString = nil;
1229
    if (update)
1230
        queryString = @"?update=";
1231
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1232
    [request prepareObjectRequestWithETag:nil 
1233
                              contentType:nil 
1234
                          contentEncoding:contentEncoding 
1235
                       contentDisposition:contentDisposition 
1236
                                 manifest:manifest 
1237
                                  sharing:sharing 
1238
                                 isPublic:isPublic 
1239
                                 metadata:metadata];
1240
    return request;
1241
}
1242

    
1243
// POST storageURL/container/object?[update=] (update metadata) [If-Match]
1244
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1245
                                   contentEncoding:(NSString *)contentEncoding 
1246
                                contentDisposition:(NSString *)contentDisposition 
1247
                                          manifest:(NSString *)manifest 
1248
                                           sharing:(NSString *)sharing 
1249
                                          isPublic:(NSUInteger)isPublic 
1250
                                          metadata:(NSDictionary *)metadata 
1251
                                            update:(BOOL)update 
1252
                                           ifMatch:(NSString *)matchETag {
1253
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName 
1254
                                                                         contentEncoding:contentEncoding 
1255
                                                                      contentDisposition:contentDisposition 
1256
                                                                                manifest:manifest 
1257
                                                                                 sharing:sharing 
1258
                                                                                isPublic:isPublic 
1259
                                                                                metadata:metadata 
1260
                                                                                  update:update];
1261
    [request addRequestIfMatchHeader:matchETag];
1262
    return request;                                                                          
1263
}
1264

    
1265
// POST storageURL/container/object?[update=] (update metadata) [If-None-Match]
1266
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1267
                                   contentEncoding:(NSString *)contentEncoding 
1268
                                contentDisposition:(NSString *)contentDisposition 
1269
                                          manifest:(NSString *)manifest 
1270
                                           sharing:(NSString *)sharing 
1271
                                          isPublic:(NSUInteger)isPublic 
1272
                                          metadata:(NSDictionary *)metadata 
1273
                                            update:(BOOL)update 
1274
                                       ifNoneMatch:(NSString *)matchETag {
1275
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName 
1276
                                                                         contentEncoding:contentEncoding 
1277
                                                                      contentDisposition:contentDisposition 
1278
                                                                                manifest:manifest 
1279
                                                                                 sharing:sharing 
1280
                                                                                isPublic:isPublic 
1281
                                                                                metadata:metadata 
1282
                                                                                  update:update];
1283
    [request addRequestIfNoneMatchHeader:matchETag];
1284
    return request;                                                                          
1285
}
1286

    
1287
// POST storageURL/container/object?[update=] (update data from ASIPithosObject with data)
1288
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object 
1289
                                        update:(BOOL)update 
1290
                                  contentRange:(NSString *)contentRange {
1291
    NSUInteger isPublic = ASIPithosObjectRequestPublicIgnore;
1292
    if (object.publicURI) {
1293
        isPublic = ASIPithosObjectRequestPublicTrue;
1294
        if ([object.publicURI isEqualToString:@""])
1295
            isPublic = ASIPithosObjectRequestPublicFalse;
1296
    }
1297
    return [self updateObjectDataRequestWithContainerName:containerName objectName:object.name 
1298
                                          contentEncoding:object.contentEncoding 
1299
                                       contentDisposition:object.contentDisposition 
1300
                                                 manifest:object.manifest 
1301
                                                  sharing:object.sharing 
1302
                                                 isPublic:isPublic
1303
                                                 metadata:object.metadata 
1304
                                                   update:update 
1305
                                             contentRange:contentRange 
1306
                                                    bytes:[NSNumber numberWithUnsignedLong:object.bytes]
1307
                                                    data:object.data];
1308
}
1309

    
1310
// POST storageURL/container/object?[update=] (update data from ASIPithosObject with data) [If-Match]
1311
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object 
1312
                                        update:(BOOL)update 
1313
                                  contentRange:(NSString *)contentRange 
1314
                                       ifMatch:(NSString *)matchETag {
1315
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName object:object 
1316
                                                                              update:update 
1317
                                                                        contentRange:contentRange];
1318
    [request addRequestIfMatchHeader:matchETag];
1319
    return request;                                                                          
1320
}
1321

    
1322
// POST storageURL/container/object?[update=] (update data from ASIPithosObject with data) [If-None-Match]
1323
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object 
1324
                                        update:(BOOL)update 
1325
                                  contentRange:(NSString *)contentRange 
1326
                                   ifNoneMatch:(NSString *)matchETag {
1327
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName object:object 
1328
                                                                              update:update 
1329
                                                                        contentRange:contentRange];
1330
    [request addRequestIfNoneMatchHeader:matchETag];
1331
    return request;                                                                          
1332
}
1333

    
1334
// POST storageURL/container/object?[update=] (update data from NSData)
1335
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1336
                               contentEncoding:(NSString *)contentEncoding 
1337
                            contentDisposition:(NSString *)contentDisposition 
1338
                                      manifest:(NSString *)manifest 
1339
                                       sharing:(NSString *)sharing 
1340
                                      isPublic:(NSUInteger)isPublic 
1341
                                      metadata:(NSDictionary *)metadata 
1342
                                        update:(BOOL)update 
1343
                                  contentRange:(NSString *)contentRange 
1344
                                         bytes:(NSNumber *)bytes 
1345
                                          data:(NSData *)data {
1346
    NSString *queryString = nil;
1347
    if (update)
1348
        queryString = @"?update=";
1349
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1350
    [request prepareObjectRequestWithETag:nil
1351
                              contentType:@"application/octet-stream"
1352
                          contentEncoding:contentEncoding 
1353
                       contentDisposition:contentDisposition 
1354
                                 manifest:manifest 
1355
                                  sharing:sharing 
1356
                                 isPublic:isPublic 
1357
                                 metadata:metadata];
1358
    if (contentRange)
1359
        [request addRequestHeader:@"Content-Range" value:contentRange];
1360
    if (bytes)
1361
        [request addRequestHeader:@"X-Object-Bytes" value:[NSString stringWithFormat:@"%lu", [bytes unsignedLongValue]]];
1362
	[request appendPostData:data];
1363
	return request;
1364
}
1365

    
1366
// POST storageURL/container/object?[update=] (update data from NSData) [If-Match]
1367
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1368
                               contentEncoding:(NSString *)contentEncoding 
1369
                            contentDisposition:(NSString *)contentDisposition 
1370
                                      manifest:(NSString *)manifest 
1371
                                       sharing:(NSString *)sharing 
1372
                                      isPublic:(NSUInteger)isPublic 
1373
                                      metadata:(NSDictionary *)metadata 
1374
                                        update:(BOOL)update 
1375
                                  contentRange:(NSString *)contentRange 
1376
                                         bytes:(NSNumber *)bytes 
1377
                                          data:(NSData *)data 
1378
                                       ifMatch:(NSString *)matchETag {
1379
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1380
                                                                     contentEncoding:contentEncoding 
1381
                                                                  contentDisposition:contentDisposition 
1382
                                                                            manifest:manifest 
1383
                                                                             sharing:sharing 
1384
                                                                            isPublic:isPublic 
1385
                                                                            metadata:metadata 
1386
                                                                              update:update 
1387
                                                                        contentRange:contentRange 
1388
                                                                               bytes:bytes 
1389
                                                                                data:data];
1390
    [request addRequestIfMatchHeader:matchETag];
1391
    return request;                                                                          
1392
}
1393

    
1394
// POST storageURL/container/object?[update=] (update data from NSData) [If-None-Match]
1395
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1396
                               contentEncoding:(NSString *)contentEncoding 
1397
                            contentDisposition:(NSString *)contentDisposition 
1398
                                      manifest:(NSString *)manifest 
1399
                                       sharing:(NSString *)sharing 
1400
                                      isPublic:(NSUInteger)isPublic 
1401
                                      metadata:(NSDictionary *)metadata 
1402
                                        update:(BOOL)update 
1403
                                  contentRange:(NSString *)contentRange 
1404
                                         bytes:(NSNumber *)bytes 
1405
                                          data:(NSData *)data 
1406
                                   ifNoneMatch:(NSString *)matchETag {
1407
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1408
                                                                     contentEncoding:contentEncoding 
1409
                                                                  contentDisposition:contentDisposition 
1410
                                                                            manifest:manifest 
1411
                                                                             sharing:sharing 
1412
                                                                            isPublic:isPublic 
1413
                                                                            metadata:metadata 
1414
                                                                              update:update 
1415
                                                                        contentRange:contentRange 
1416
                                                                               bytes:bytes 
1417
                                                                                data:data];
1418
    [request addRequestIfNoneMatchHeader:matchETag];
1419
    return request;                                                                          
1420
}
1421

    
1422
// POST storageURL/container/object?[update=] (update data from file)
1423
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1424
                               contentEncoding:(NSString *)contentEncoding 
1425
                            contentDisposition:(NSString *)contentDisposition 
1426
                                      manifest:(NSString *)manifest 
1427
                                       sharing:(NSString *)sharing 
1428
                                      isPublic:(NSUInteger)isPublic 
1429
                                      metadata:(NSDictionary *)metadata 
1430
                                        update:(BOOL)update 
1431
                                  contentRange:(NSString *)contentRange 
1432
                                         bytes:(NSNumber *)bytes 
1433
                                          file:(NSString *)filePath {
1434
    NSString *queryString = nil;
1435
    if (update)
1436
        queryString = @"?update=";
1437
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1438
    [request prepareObjectRequestWithETag:nil
1439
                              contentType:@"application/octet-stream"
1440
                          contentEncoding:contentEncoding 
1441
                       contentDisposition:contentDisposition 
1442
                                 manifest:manifest 
1443
                                  sharing:sharing 
1444
                                 isPublic:isPublic 
1445
                                 metadata:metadata];
1446
    if (contentRange)
1447
        [request addRequestHeader:@"Content-Range" value:contentRange];
1448
    if (bytes)
1449
        [request addRequestHeader:@"X-Object-Bytes" value:[NSString stringWithFormat:@"%lu", [bytes unsignedLongValue]]];
1450
	request.shouldStreamPostDataFromDisk = YES;
1451
    request.postBodyFilePath = filePath;
1452
	return request;
1453
}
1454

    
1455
// POST storageURL/container/object?[update=] (update data from file) [If-Match]
1456
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1457
                               contentEncoding:(NSString *)contentEncoding 
1458
                            contentDisposition:(NSString *)contentDisposition 
1459
                                      manifest:(NSString *)manifest 
1460
                                       sharing:(NSString *)sharing 
1461
                                      isPublic:(NSUInteger)isPublic 
1462
                                      metadata:(NSDictionary *)metadata 
1463
                                        update:(BOOL)update 
1464
                                  contentRange:(NSString *)contentRange 
1465
                                         bytes:(NSNumber *)bytes 
1466
                                          file:(NSString *)filePath 
1467
                                       ifMatch:(NSString *)matchETag {
1468
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1469
                                                                     contentEncoding:contentEncoding 
1470
                                                                  contentDisposition:contentDisposition 
1471
                                                                            manifest:manifest 
1472
                                                                             sharing:sharing 
1473
                                                                            isPublic:isPublic 
1474
                                                                            metadata:metadata 
1475
                                                                              update:update 
1476
                                                                        contentRange:contentRange 
1477
                                                                               bytes:bytes 
1478
                                                                                file:filePath];
1479
    [request addRequestIfMatchHeader:matchETag];
1480
    return request;                                                                          
1481
}
1482

    
1483
// POST storageURL/container/object?[update=] (update data from file) [If-None-Match]
1484
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1485
                               contentEncoding:(NSString *)contentEncoding 
1486
                            contentDisposition:(NSString *)contentDisposition 
1487
                                      manifest:(NSString *)manifest 
1488
                                       sharing:(NSString *)sharing 
1489
                                      isPublic:(NSUInteger)isPublic 
1490
                                      metadata:(NSDictionary *)metadata 
1491
                                        update:(BOOL)update 
1492
                                  contentRange:(NSString *)contentRange 
1493
                                         bytes:(NSNumber *)bytes 
1494
                                          file:(NSString *)filePath 
1495
                                   ifNoneMatch:(NSString *)matchETag {
1496
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1497
                                                                     contentEncoding:contentEncoding 
1498
                                                                  contentDisposition:contentDisposition 
1499
                                                                            manifest:manifest 
1500
                                                                             sharing:sharing 
1501
                                                                            isPublic:isPublic 
1502
                                                                            metadata:metadata 
1503
                                                                              update:update 
1504
                                                                        contentRange:contentRange 
1505
                                                                               bytes:bytes 
1506
                                                                                file:filePath];
1507
    [request addRequestIfNoneMatchHeader:matchETag];
1508
    return request;                                                                          
1509
}
1510

    
1511
// POST storageURL/container/object?[update=] (update data from source)
1512
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1513
                               contentEncoding:(NSString *)contentEncoding 
1514
                            contentDisposition:(NSString *)contentDisposition 
1515
                                      manifest:(NSString *)manifest 
1516
                                       sharing:(NSString *)sharing 
1517
                                      isPublic:(NSUInteger)isPublic 
1518
                                      metadata:(NSDictionary *)metadata 
1519
                                        update:(BOOL)update 
1520
                                  contentRange:(NSString *)contentRange 
1521
                                         bytes:(NSNumber *)bytes 
1522
                           sourceContainerName:(NSString *)sourceContainerName 
1523
                              sourceObjectName:(NSString *)sourceObjectName 
1524
                                 sourceAccount:(NSString *)sourceAccount
1525
                                 sourceVersion:(NSString *)sourceVersion {
1526
    NSString *queryString = nil;
1527
    if (update)
1528
        queryString = @"?update=";
1529
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1530
    [request prepareObjectRequestWithETag:nil
1531
                              contentType:nil
1532
                          contentEncoding:contentEncoding 
1533
                       contentDisposition:contentDisposition 
1534
                                 manifest:manifest 
1535
                                  sharing:sharing 
1536
                                 isPublic:isPublic 
1537
                                 metadata:metadata];
1538
    if (contentRange)
1539
        [request addRequestHeader:@"Content-Range" value:contentRange];
1540
    if (bytes)
1541
        [request addRequestHeader:@"X-Object-Bytes" value:[NSString stringWithFormat:@"%lu", [bytes unsignedLongValue]]];
1542
    [request addRequestHeader:@"X-Source-Object" 
1543
                        value:[[NSString stringWithFormat:@"/%@/%@", sourceContainerName, sourceObjectName] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
1544
    if (sourceAccount)
1545
        [request addRequestHeader:@"X-Source-Account" 
1546
                            value:[sourceAccount stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
1547
    if (sourceVersion)
1548
        [request addRequestHeader:@"X-Source-Version" value:sourceVersion];
1549
	return request;
1550

    
1551
}
1552

    
1553
// POST storageURL/container/object?[update=] (update data from source) [If-Match]
1554
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1555
                               contentEncoding:(NSString *)contentEncoding 
1556
                            contentDisposition:(NSString *)contentDisposition 
1557
                                      manifest:(NSString *)manifest 
1558
                                       sharing:(NSString *)sharing 
1559
                                      isPublic:(NSUInteger)isPublic 
1560
                                      metadata:(NSDictionary *)metadata 
1561
                                        update:(BOOL)update 
1562
                                  contentRange:(NSString *)contentRange 
1563
                                         bytes:(NSNumber *)bytes 
1564
                           sourceContainerName:(NSString *)sourceContainerName 
1565
                              sourceObjectName:(NSString *)sourceObjectName 
1566
                                 sourceAccount:(NSString *)sourceAccount
1567
                                 sourceVersion:(NSString *)sourceVersion 
1568
                                       ifMatch:(NSString *)matchETag {
1569
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1570
                                                                     contentEncoding:contentEncoding 
1571
                                                                  contentDisposition:contentDisposition 
1572
                                                                            manifest:manifest 
1573
                                                                             sharing:sharing 
1574
                                                                            isPublic:isPublic 
1575
                                                                            metadata:metadata 
1576
                                                                              update:update 
1577
                                                                        contentRange:contentRange 
1578
                                                                               bytes:bytes 
1579
                                                                 sourceContainerName:sourceContainerName 
1580
                                                                    sourceObjectName:sourceObjectName 
1581
                                                                       sourceAccount:sourceAccount 
1582
                                                                       sourceVersion:sourceVersion];
1583
    [request addRequestIfMatchHeader:matchETag];
1584
    return request;                                                                          
1585
}
1586

    
1587
// POST storageURL/container/object?[update=] (update data from source) [If-None-Match]
1588
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1589
                               contentEncoding:(NSString *)contentEncoding 
1590
                            contentDisposition:(NSString *)contentDisposition 
1591
                                      manifest:(NSString *)manifest 
1592
                                       sharing:(NSString *)sharing 
1593
                                      isPublic:(NSUInteger)isPublic 
1594
                                      metadata:(NSDictionary *)metadata 
1595
                                        update:(BOOL)update 
1596
                                  contentRange:(NSString *)contentRange 
1597
                                         bytes:(NSNumber *)bytes 
1598
                           sourceContainerName:(NSString *)sourceContainerName 
1599
                              sourceObjectName:(NSString *)sourceObjectName 
1600
                                 sourceAccount:(NSString *)sourceAccount
1601
                                 sourceVersion:(NSString *)sourceVersion 
1602
                                   ifNoneMatch:(NSString *)matchETag {
1603
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1604
                                                                     contentEncoding:contentEncoding 
1605
                                                                  contentDisposition:contentDisposition 
1606
                                                                            manifest:manifest 
1607
                                                                             sharing:sharing 
1608
                                                                            isPublic:isPublic 
1609
                                                                            metadata:metadata 
1610
                                                                              update:update 
1611
                                                                        contentRange:contentRange 
1612
                                                                               bytes:bytes 
1613
                                                                 sourceContainerName:sourceContainerName 
1614
                                                                    sourceObjectName:sourceObjectName 
1615
                                                                       sourceAccount:sourceAccount 
1616
                                                                       sourceVersion:sourceVersion];
1617
    [request addRequestIfNoneMatchHeader:matchETag];
1618
    return request;                                                                          
1619
}
1620

    
1621
#pragma mark -
1622
#pragma mark DELETE
1623

    
1624
// DELETE storageURL/container/object
1625
+ (id)deleteObjectRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
1626
    return [self storageRequestWithMethod:@"DELETE" containerName:containerName objectName:objectName];
1627
}
1628

    
1629
// DELETE storageURL/container/object?[until=untilTimestamp]
1630
+ (id)deleteObjectRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName until:(NSDate *)untilTimestamp {
1631
    NSString *queryString = nil;
1632
    if (untilTimestamp)
1633
        queryString = [NSString stringWithFormat:@"?until=%d", (int)[untilTimestamp timeIntervalSince1970]];
1634
	return [self storageRequestWithMethod:@"DELETE" containerName:containerName objectName:objectName queryString:queryString];
1635
}
1636

    
1637
#pragma mark -
1638
#pragma mark NSXMLParserDelegate
1639

    
1640
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
1641
	self.currentElement = elementName;
1642
    if ((objectRequestType == ASIPithosObjectRequestHashmap) && [elementName isEqualToString:@"object"]) {
1643
        blockSize = [[attributeDict valueForKey:@"block_size"] intValue];
1644
        blockHash = [[NSString alloc] initWithString:[attributeDict valueForKey:@"block_hash"]];
1645
        bytes = [[attributeDict valueForKey:@"bytes"] intValue];
1646
    } else if ((objectRequestType == ASIPithosObjectRequestVersions) && [elementName isEqualToString:@"version"]) {
1647
        self.currentObject = [ASIPithosObject object];
1648
        currentObject.versionTimestamp = [NSDate dateWithTimeIntervalSince1970:[[attributeDict valueForKey:@"timestamp"] doubleValue]];
1649
	}
1650
	self.currentContent = @"";
1651
}
1652

    
1653
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
1654
	if ((objectRequestType == ASIPithosObjectRequestHashmap) && [elementName isEqualToString:@"hash"]) {
1655
        [hashes addObject:currentContent];
1656
    } else if (objectRequestType == ASIPithosObjectRequestVersions) {
1657
        if ([elementName isEqualToString:@"version"]) {
1658
            currentObject.version = currentContent;
1659
        } else if ([elementName isEqualToString:@"object"]) {
1660
            [versions addObject:currentObject];
1661
            self.currentObject = nil;
1662
        }
1663
	}
1664
}
1665

    
1666
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
1667
    self.currentContent = [currentContent stringByAppendingString:string];
1668
}
1669

    
1670
@end