Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Classes / Pithos / ASIPithosObjectRequest.m @ 9d03a93c

History | View | Annotate | Download (98.2 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" value:manifest];
129
    if (sharing)
130
        [self addRequestHeader:@"X-Object-Sharing" value:sharing];
131
    if (isPublic == ASIPithosObjectRequestPublicTrue) {
132
        [self addRequestHeader:@"X-Object-Public" value:@"true"];
133
    } else if (isPublic == ASIPithosObjectRequestPublicFalse) {
134
        [self addRequestHeader:@"X-Object-Public" value:@"false"];
135
    }
136
    
137
    if (newMetadata) {
138
        for (NSString *key in [newMetadata keyEnumerator]) {
139
            [self addRequestHeader:[NSString stringWithFormat:@"X-Object-Meta-%@", key] value:[newMetadata objectForKey:key]];
140
        }
141
    }
142
}
143

    
144
#pragma mark -
145
#pragma mark HEAD
146

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

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

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

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

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

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

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

    
202
- (NSUInteger)objectContentLength {
203
	return [[[self responseHeaders] objectForKey:@"Content-Length"] intValue];
204
}
205

    
206
- (NSString *)contentType {
207
	return [[self responseHeaders] objectForKey:@"Content-Type"];
208
}
209

    
210
- (NSDate *)lastModified {
211
    NSString *lastModifiedString = [[self responseHeaders] objectForKey:@"Last-Modified"];
212
    if (lastModifiedString)
213
        return [[self dateFormatterWithFormatId:1] dateFromString:lastModifiedString];
214
    return nil;
215
}
216

    
217
- (NSString *)contentEncoding {
218
	return [[self responseHeaders] objectForKey:@"Content-Encoding"];
219
}
220

    
221
- (NSString *)contentDisposition {
222
	return [[self responseHeaders] objectForKey:@"Content-Disposition"];
223
}
224

    
225
- (NSString *)version {
226
	return [[self responseHeaders] objectForKey:@"X-Object-Version"];
227
}
228

    
229
- (NSDate *)versionTimestamp {
230
    NSString *versionTimestampString = [[self responseHeaders] objectForKey:@"X-Object-Version-Timestamp"];
231
    if (versionTimestampString)
232
        return [[self dateFormatterWithFormatId:1] dateFromString:versionTimestampString];
233
    return nil;
234
}
235

    
236
- (NSString *)modifiedBy {
237
	return [[self responseHeaders] objectForKey:@"X-Object-Modified-By"];
238
}
239

    
240
- (NSString *)manifest {
241
	return [[self responseHeaders] objectForKey:@"X-Object-Manifest"];
242
}
243

    
244
- (NSString *)sharing {
245
	return [[self responseHeaders] objectForKey:@"X-Object-Sharing"];
246
}
247

    
248
- (NSString *)sharedBy {
249
	return [[self responseHeaders] objectForKey:@"X-Object-Shared-By"];
250
}
251

    
252
- (NSString *)publicURI {
253
	return [[self responseHeaders] objectForKey:@"X-Object-Public"];
254
}
255

    
256
- (NSDictionary *)metadata {
257
    if (metadata == nil) {
258
        metadata = [self getHeadersDictionaryForPrefix:@"X-Object-Meta-"];
259
        [metadata retain];
260
    }
261
    return metadata;
262
}
263

    
264
- (NSString *)allowedTo {
265
    return [[self responseHeaders] objectForKey:@"X-Object-Allowed-To"];
266
}
267

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

    
296
#pragma mark -
297
#pragma mark GET
298

    
299
// GET storageURL/container/object
300
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
301
    return [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName];
302
}
303

    
304
// GET storageURL/container/object?[version=version]
305
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName version:(NSString *)version {
306
    NSString *queryString = nil;
307
    if (version)
308
        queryString = [NSString stringWithFormat:@"?version=%@", version];
309
	return [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:queryString];
310
}
311

    
312
// GET storageURL/container/object?[version=version] [If-Match]
313
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
314
                                 version:(NSString *)version 
315
                                 ifMatch:(NSString *)matchETag {
316
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
317
    [request addRequestIfMatchHeader:matchETag];
318
    return request;
319
}
320

    
321
// GET storageURL/container/object?[version=version] [If-None-Match]
322
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
323
                                 version:(NSString *)version 
324
                             ifNoneMatch:(NSString *)matchETag {
325
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
326
    [request addRequestIfNoneMatchHeader:matchETag];
327
    return request;
328
}
329

    
330
// GET storageURL/container/object?[version=version] [If-Modified-Since]
331
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
332
                                 version:(NSString *)version 
333
                         ifModifiedSince:(NSDate *)sinceTimestamp {
334
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
335
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
336
    return request;
337
}
338

    
339
// GET storageURL/container/object?[version=version] [If-Unmodified-Since]
340
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
341
                                 version:(NSString *)version 
342
                       ifUnmodifiedSince:(NSDate *)sinceTimestamp {
343
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
344
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
345
    return request;
346
}
347

    
348
// GET storageURL/container/object?[version=version] [Range [If-Range]]
349
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
350
                                 version:(NSString *)version 
351
                                   range:(NSString *)rangeString {
352
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
353
    [request addRequestRangeHeader:rangeString];
354
    return request;
355
}
356

    
357
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
358
                                 version:(NSString *)version 
359
                                   range:(NSString *)rangeString 
360
                             ifRangeETag:(NSString *)rangeETag {
361
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
362
    [request addRequestRangeHeader:rangeString ifRangeETag:rangeETag];
363
    return request;
364
}
365

    
366
+ (id)objectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
367
                                 version:(NSString *)version 
368
                                   range:(NSString *)rangeString 
369
                        ifRangeTimestamp:(NSDate *)rangeTimestamp {
370
    ASIPithosObjectRequest *request = [self objectDataRequestWithContainerName:containerName objectName:objectName version:version];
371
    [request addRequestRangeHeader:rangeString ifRangeTimestamp:rangeTimestamp];
372
    return request;
373
}
374

    
375
- (NSData *)data {
376
    return [self responseData];
377
}
378

    
379
// GET storageURL/container/object?format=xml&hashmap=
380
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
381
    ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:@"?format=xml&hashmap="];
382
    request.objectRequestType = ASIPithosObjectRequestHashmap;
383
    return request;
384
}
385

    
386
// GET storageURL/container/object?format=xml&hashmap=[&version=version]
387
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName version:(NSString *)version {
388
    NSString *queryString = @"?format=xml&hashmap=";
389
    if (version)
390
        queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&version=%@", version]];
391
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:queryString];
392
    request.objectRequestType = ASIPithosObjectRequestHashmap;
393
    return request;
394
}
395

    
396
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-Match]
397
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
398
                                    version:(NSString *)version 
399
                                    ifMatch:(NSString *)matchETag {
400
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
401
    [request addRequestIfMatchHeader:matchETag];
402
    return request;
403
}
404

    
405
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-NoneMatch]
406
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
407
                                    version:(NSString *)version 
408
                                ifNoneMatch:(NSString *)matchETag {
409
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
410
    [request addRequestIfNoneMatchHeader:matchETag];
411
    return request;
412
}
413

    
414
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-Modified-Since]
415
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
416
                                    version:(NSString *)version 
417
                            ifModifiedSince:(NSDate *)sinceTimestamp {
418
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
419
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
420
    return request;
421
}
422

    
423
// GET storageURL/container/object?format=xml&hashmap=[&version=version] [If-Unmodified-Since]
424
+ (id)objectHashmapRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
425
                                    version:(NSString *)version 
426
                          ifUnmodifiedSince:(NSDate *)sinceTimestamp {
427
    ASIPithosObjectRequest *request = [self objectHashmapRequestWithContainerName:containerName objectName:objectName version:version];
428
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
429
    return request;
430
}
431

    
432
- (NSUInteger)blockSize {
433
    if (hashes == nil)
434
        [self parseXMLData];
435
    return blockSize;
436
}
437

    
438
- (NSString *)blockHash {
439
    if (hashes == nil)
440
        [self parseXMLData];
441
    return blockHash;
442
}
443

    
444
- (NSArray *)hashes {
445
    if (hashes == nil)
446
        [self parseXMLData];
447
    return hashes;
448
}
449

    
450
- (NSUInteger)bytes {
451
    if (hashes == nil)
452
        [self parseXMLData];
453
    return bytes;
454
}
455

    
456
// GET storageURL/container/object?format=xml&version=list
457
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
458
    ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"GET" containerName:containerName objectName:objectName queryString:@"?format=xml&version=list"];
459
    request.objectRequestType = ASIPithosObjectRequestVersions;
460
    return request;
461
}
462

    
463
// GET storageURL/container/object?format=xml&version=list [If-Match]
464
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifMatch:(NSString *)matchETag {
465
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
466
    [request addRequestIfMatchHeader:matchETag];
467
    return request;
468
}
469

    
470
// GET storageURL/container/object?format=xml&version=list [If-None-Match]
471
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifNoneMatch:(NSString *)matchETag {
472
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
473
    [request addRequestIfNoneMatchHeader:matchETag];
474
    return request;
475
}
476

    
477
// GET storageURL/container/object?format=xml&version=list [If-Modified-Since]
478
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifModifiedSince:(NSDate *)sinceTimestamp {
479
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
480
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
481
    return request;
482
}
483

    
484
// GET storageURL/container/object?format=xml&version=list [If-Unmodified-Since]
485
+ (id)objectVersionsRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName ifUnmodifiedSince:(NSDate *)sinceTimestamp {
486
    ASIPithosObjectRequest *request = [self objectVersionsRequestWithContainerName:containerName objectName:objectName];
487
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
488
    return request;
489
}
490

    
491
- (NSArray *)versions {
492
    if (versions == nil)
493
        [self parseXMLData];
494
    return versions;
495
}
496

    
497
#pragma mark -
498
#pragma mark PUT, COPY, MOVE
499

    
500
// PUT storageURL/container/object (from ASIPithosObject with data)
501
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object {
502
    NSUInteger isPublic = ASIPithosObjectRequestPublicIgnore;
503
    if (object.publicURI) {
504
        isPublic = ASIPithosObjectRequestPublicTrue;
505
        if ([object.publicURI isEqualToString:@""])
506
            isPublic = ASIPithosObjectRequestPublicFalse;
507
    }
508
    return [self writeObjectDataRequestWithContainerName:containerName 
509
                                              objectName:object.name 
510
                                                    eTag:object.hash 
511
                                             contentType:object.contentType 
512
                                         contentEncoding:object.contentEncoding 
513
                                      contentDisposition:object.contentDisposition 
514
                                                manifest:object.manifest 
515
                                                 sharing:object.sharing 
516
                                                isPublic:isPublic
517
                                                metadata:object.metadata 
518
                                                    data:object.data];
519
}
520

    
521
// PUT storageURL/container/object (from ASIPithosObject with data) [If-Match]
522
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object ifMatch:(NSString *)matchETag {
523
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName object:object];
524
    [request addRequestIfMatchHeader:matchETag];
525
    return request;
526
}
527

    
528
// PUT storageURL/container/object (from ASIPithosObject with data) [If-None-Match]
529
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object ifNoneMatch:(NSString *)matchETag  {
530
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName object:object];
531
    [request addRequestIfNoneMatchHeader:matchETag];
532
    return request;
533
}
534

    
535
// PUT storageURL/container/object (from NSData)
536
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
537
                                   objectName:(NSString *)objectName 
538
                                         eTag:(NSString *)eTag 
539
                                  contentType:(NSString *)contentType 
540
                              contentEncoding:(NSString *)contentEncoding 
541
                           contentDisposition:(NSString *)contentDisposition 
542
                                     manifest:(NSString *)manifest 
543
                                      sharing:(NSString *)sharing 
544
                                     isPublic:(NSUInteger)isPublic 
545
                                     metadata:(NSDictionary *)metadata 
546
                                         data:(NSData *)data {
547
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
548
    [request prepareObjectRequestWithETag:eTag 
549
                              contentType:contentType 
550
                          contentEncoding:contentEncoding 
551
                       contentDisposition:contentDisposition 
552
                                 manifest:manifest 
553
                                  sharing:sharing 
554
                                 isPublic:isPublic 
555
                                 metadata:metadata];
556
	[request appendPostData:data];
557
    request.requestMethod = @"PUT";
558
	return request;
559
}
560

    
561
// PUT storageURL/container/object (from NSData) [If-Match]
562
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
563
                                   objectName:(NSString *)objectName 
564
                                         eTag:(NSString *)eTag 
565
                                  contentType:(NSString *)contentType 
566
                              contentEncoding:(NSString *)contentEncoding 
567
                           contentDisposition:(NSString *)contentDisposition 
568
                                     manifest:(NSString *)manifest 
569
                                      sharing:(NSString *)sharing 
570
                                     isPublic:(NSUInteger)isPublic 
571
                                     metadata:(NSDictionary *)metadata 
572
                                         data:(NSData *)data 
573
                                      ifMatch:(NSString *)matchETag {
574
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
575
                                                                               eTag:eTag 
576
                                                                        contentType:contentType 
577
                                                                    contentEncoding:contentEncoding 
578
                                                                 contentDisposition:contentDisposition 
579
                                                                           manifest:manifest 
580
                                                                            sharing:sharing 
581
                                                                           isPublic:isPublic 
582
                                                                           metadata:metadata 
583
                                                                               data:data];
584
    [request addRequestIfMatchHeader:matchETag];
585
    return request;                                                                          
586
}
587

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

    
615
// PUT storageURL/container/object (from file)
616
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
617
                                   objectName:(NSString *)objectName 
618
                                         eTag:(NSString *)eTag 
619
                                  contentType:(NSString *)contentType 
620
                              contentEncoding:(NSString *)contentEncoding 
621
                           contentDisposition:(NSString *)contentDisposition 
622
                                     manifest:(NSString *)manifest 
623
                                      sharing:(NSString *)sharing 
624
                                     isPublic:(NSUInteger)isPublic 
625
                                     metadata:(NSDictionary *)metadata 
626
                                         file:(NSString *)filePath {
627
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
628
    [request prepareObjectRequestWithETag:eTag 
629
                              contentType:contentType 
630
                          contentEncoding:contentEncoding 
631
                       contentDisposition:contentDisposition 
632
                                 manifest:manifest 
633
                                  sharing:sharing 
634
                                 isPublic:isPublic 
635
                                 metadata:metadata];
636
	request.shouldStreamPostDataFromDisk = YES;
637
    request.postBodyFilePath = filePath;
638
    request.requestMethod = @"PUT";
639
	return request;    
640
}
641

    
642
// PUT storageURL/container/object (from file) [If-Match]
643
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
644
                                   objectName:(NSString *)objectName 
645
                                         eTag:(NSString *)eTag 
646
                                  contentType:(NSString *)contentType 
647
                              contentEncoding:(NSString *)contentEncoding 
648
                           contentDisposition:(NSString *)contentDisposition 
649
                                     manifest:(NSString *)manifest 
650
                                      sharing:(NSString *)sharing 
651
                                     isPublic:(NSUInteger)isPublic 
652
                                     metadata:(NSDictionary *)metadata 
653
                                         file:(NSString *)filePath 
654
                                      ifMatch:(NSString *)matchETag {
655
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
656
                                                                               eTag:eTag 
657
                                                                        contentType:contentType 
658
                                                                    contentEncoding:contentEncoding 
659
                                                                 contentDisposition:contentDisposition 
660
                                                                           manifest:manifest 
661
                                                                            sharing:sharing 
662
                                                                           isPublic:isPublic 
663
                                                                           metadata:metadata 
664
                                                                               file:filePath];
665
    [request addRequestIfMatchHeader:matchETag];
666
    return request;                                                                          
667
}
668

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

    
696
// PUT storageURL/container/object (from hashes)
697
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
698
                                   objectName:(NSString *)objectName 
699
                                  contentType:(NSString *)contentType 
700
                              contentEncoding:(NSString *)contentEncoding 
701
                           contentDisposition:(NSString *)contentDisposition 
702
                                     manifest:(NSString *)manifest 
703
                                      sharing:(NSString *)sharing 
704
                                     isPublic:(NSUInteger)isPublic 
705
                                     metadata:(NSDictionary *)metadata 
706
                                    blockSize:(NSUInteger)blockSize 
707
                                    blockHash:(NSString *)blockHash 
708
                                       hashes:(NSArray *)hashes 
709
                                        bytes:(NSUInteger)bytes {
710
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName queryString:@"?format=xml&hashmap="];
711
    [request prepareObjectRequestWithETag:nil 
712
                              contentType:contentType 
713
                          contentEncoding:contentEncoding 
714
                       contentDisposition:contentDisposition 
715
                                 manifest:manifest 
716
                                  sharing:sharing 
717
                                 isPublic:isPublic 
718
                                 metadata:metadata];
719
    NSString *dataString = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?><object name=\"%@\" bytes=\"%lu\" block_size=\"%lu\" block_hash=\"%@\">", 
720
                            (NSString *)CFXMLCreateStringByEscapingEntities(NULL, (CFStringRef)objectName , NULL), 
721
                            bytes, blockSize, blockHash];
722
    for (NSString *hash in hashes) {
723
        dataString = [dataString stringByAppendingFormat:@"<hash>%@</hash>", hash];
724
    }
725
    dataString = [dataString stringByAppendingString:@"</object>"];
726
	[request appendPostData:[dataString dataUsingEncoding:NSUTF8StringEncoding]];
727
    request.requestMethod = @"PUT";
728
	return request;    
729
}
730

    
731
// PUT storageURL/container/object (from hashes) [If-Match]
732
+ (id)writeObjectDataRequestWithContainerName:(NSString *)containerName 
733
                                   objectName:(NSString *)objectName 
734
                                  contentType:(NSString *)contentType 
735
                              contentEncoding:(NSString *)contentEncoding 
736
                           contentDisposition:(NSString *)contentDisposition 
737
                                     manifest:(NSString *)manifest 
738
                                      sharing:(NSString *)sharing 
739
                                     isPublic:(NSUInteger)isPublic 
740
                                     metadata:(NSDictionary *)metadata 
741
                                    blockSize:(NSUInteger)blockSize 
742
                                    blockHash:(NSString *)blockHash 
743
                                       hashes:(NSArray *)hashes 
744
                                        bytes:(NSUInteger)bytes 
745
                                      ifMatch:(NSString *)matchETag {
746
    ASIPithosObjectRequest *request = [self writeObjectDataRequestWithContainerName:containerName objectName:objectName 
747
                                                                        contentType:contentType 
748
                                                                    contentEncoding:contentEncoding 
749
                                                                 contentDisposition:contentDisposition 
750
                                                                           manifest:manifest 
751
                                                                            sharing:sharing 
752
                                                                           isPublic:isPublic 
753
                                                                           metadata:metadata 
754
                                                                          blockSize:blockSize 
755
                                                                          blockHash:blockHash 
756
                                                                             hashes:hashes 
757
                                                                              bytes:bytes];
758
    [request addRequestIfMatchHeader:matchETag];
759
    return request;                                                                          
760
}
761

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

    
793
// PUT storageURL/container/object (copy from source)
794
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
795
                                  objectName:(NSString *)objectName 
796
                                 contentType:(NSString *)contentType 
797
                             contentEncoding:(NSString *)contentEncoding 
798
                          contentDisposition:(NSString *)contentDisposition 
799
                                    manifest:(NSString *)manifest 
800
                                     sharing:(NSString *)sharing 
801
                                    isPublic:(NSUInteger)isPublic 
802
                                    metadata:(NSDictionary *)metadata 
803
                         sourceContainerName:(NSString *)sourceContainerName 
804
                            sourceObjectName:(NSString *)sourceObjectName
805
                               sourceAccount:(NSString *)sourceAccount
806
                               sourceVersion:(NSString *)sourceVersion {
807
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
808
    [request prepareObjectRequestWithETag:nil 
809
                              contentType:contentType 
810
                          contentEncoding:contentEncoding 
811
                       contentDisposition:contentDisposition 
812
                                 manifest:manifest 
813
                                  sharing:sharing 
814
                                 isPublic:isPublic 
815
                                 metadata:metadata];
816
    [request addRequestHeader:@"Content-Length" value:@"0"];
817
    [request addRequestHeader:@"X-Copy-From" value:[NSString stringWithFormat:@"/%@/%@", sourceContainerName, sourceObjectName]];
818
    if (sourceAccount)
819
        [request addRequestHeader:@"X-Source-Account" value:sourceAccount];
820
    if (sourceVersion)
821
        [request addRequestHeader:@"X-Source-Version" value:sourceVersion];
822
    return request;
823
}
824

    
825
// PUT storageURL/container/object (copy from source) [If-Match]
826
+ (id)copyObjectDataRequestWithContainerName:(NSString *)containerName 
827
                                  objectName:(NSString *)objectName 
828
                                 contentType:(NSString *)contentType 
829
                             contentEncoding:(NSString *)contentEncoding 
830
                          contentDisposition:(NSString *)contentDisposition 
831
                                    manifest:(NSString *)manifest 
832
                                     sharing:(NSString *)sharing 
833
                                    isPublic:(NSUInteger)isPublic 
834
                                    metadata:(NSDictionary *)metadata 
835
                         sourceContainerName:(NSString *)sourceContainerName 
836
                            sourceObjectName:(NSString *)sourceObjectName
837
                               sourceAccount:(NSString *)sourceAccount
838
                               sourceVersion:(NSString *)sourceVersion 
839
                                     ifMatch:(NSString *)matchETag {
840
    ASIPithosObjectRequest *request = [self copyObjectDataRequestWithContainerName:containerName objectName:objectName 
841
                                                                       contentType:contentType 
842
                                                                   contentEncoding:contentEncoding 
843
                                                                contentDisposition:contentDisposition 
844
                                                                          manifest:manifest 
845
                                                                           sharing:sharing 
846
                                                                          isPublic:isPublic 
847
                                                                          metadata:metadata 
848
                                                               sourceContainerName:sourceContainerName 
849
                                                                  sourceObjectName:sourceObjectName 
850
                                                                     sourceAccount:sourceAccount
851
                                                                     sourceVersion:sourceVersion];
852
    [request addRequestIfMatchHeader:matchETag];
853
    return request;                                                                          
854
}
855

    
856
// PUT storageURL/container/object (copy from source) [If-None-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
                                 ifNoneMatch:(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 addRequestIfNoneMatchHeader:matchETag];
884
    return request;                                                                          
885
}
886

    
887
// COPY storageURL/container/object (copy to destination)
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
                    destinationContainerName:(NSString *)destinationContainerName 
898
                       destinationObjectName:(NSString *)destinationObjectName
899
                          destinationAccount:(NSString *)destinationAccount
900
                               sourceVersion:(NSString *)sourceVersion {
901
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"COPY" containerName:containerName objectName:objectName];
902
    [request prepareObjectRequestWithETag:nil 
903
                              contentType:contentType 
904
                          contentEncoding:contentEncoding 
905
                       contentDisposition:contentDisposition 
906
                                 manifest:manifest 
907
                                  sharing:sharing 
908
                                 isPublic:isPublic 
909
                                 metadata:metadata];
910
    [request addRequestHeader:@"Destination" value:[NSString stringWithFormat:@"/%@/%@", destinationContainerName, destinationObjectName]];
911
    if (destinationAccount)
912
        [request addRequestHeader:@"Destination-Account" value:destinationAccount];
913
    if (sourceVersion)
914
        [request addRequestHeader:@"X-Source-Version" value:sourceVersion];
915
    return request;
916
}
917

    
918
// COPY storageURL/container/object (copy to destination) [If-Match]
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
                                     ifMatch:(NSString *)matchETag {
933
    ASIPithosObjectRequest *request = [self copyObjectDataRequestWithContainerName:containerName objectName:objectName 
934
                                                                       contentType:contentType 
935
                                                                   contentEncoding:contentEncoding 
936
                                                                contentDisposition:contentDisposition 
937
                                                                          manifest:manifest 
938
                                                                           sharing:sharing 
939
                                                                          isPublic:isPublic 
940
                                                                          metadata:metadata 
941
                                                          destinationContainerName:destinationContainerName 
942
                                                             destinationObjectName:destinationObjectName 
943
                                                                destinationAccount:destinationAccount
944
                                                                     sourceVersion:sourceVersion];
945
    [request addRequestIfMatchHeader:matchETag];
946
    return request;                                                                          
947
}
948

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

    
980
// PUT storageURL/container/object (move from source)
981
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
982
                                  objectName:(NSString *)objectName 
983
                                 contentType:(NSString *)contentType 
984
                             contentEncoding:(NSString *)contentEncoding 
985
                          contentDisposition:(NSString *)contentDisposition 
986
                                    manifest:(NSString *)manifest 
987
                                     sharing:(NSString *)sharing 
988
                                    isPublic:(NSUInteger)isPublic 
989
                                    metadata:(NSDictionary *)metadata 
990
                         sourceContainerName:(NSString *)sourceContainerName 
991
                            sourceObjectName:(NSString *)sourceObjectName 
992
                               sourceAccount:(NSString *)sourceAccount { 
993
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName objectName:objectName];
994
    [request prepareObjectRequestWithETag:nil 
995
                              contentType:contentType 
996
                          contentEncoding:contentEncoding 
997
                       contentDisposition:contentDisposition 
998
                                 manifest:manifest 
999
                                  sharing:sharing 
1000
                                 isPublic:isPublic 
1001
                                 metadata:metadata];
1002
    [request addRequestHeader:@"Content-Length" value:@"0"];
1003
    [request addRequestHeader:@"X-Move-From" value:[NSString stringWithFormat:@"/%@/%@", sourceContainerName, sourceObjectName]];
1004
    if (sourceAccount)
1005
        [request addRequestHeader:@"X-Source-Account" value:sourceAccount];
1006
    return request;
1007
}
1008

    
1009
// PUT storageURL/container/object (move from source) [If-Match]
1010
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1011
                                  objectName:(NSString *)objectName 
1012
                                 contentType:(NSString *)contentType 
1013
                             contentEncoding:(NSString *)contentEncoding 
1014
                          contentDisposition:(NSString *)contentDisposition 
1015
                                    manifest:(NSString *)manifest 
1016
                                     sharing:(NSString *)sharing 
1017
                                    isPublic:(NSUInteger)isPublic 
1018
                                    metadata:(NSDictionary *)metadata 
1019
                         sourceContainerName:(NSString *)sourceContainerName 
1020
                            sourceObjectName:(NSString *)sourceObjectName
1021
                               sourceAccount:(NSString *)sourceAccount
1022
                                     ifMatch:(NSString *)matchETag {
1023
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1024
                                                                       contentType:contentType 
1025
                                                                   contentEncoding:contentEncoding 
1026
                                                                contentDisposition:contentDisposition 
1027
                                                                          manifest:manifest 
1028
                                                                           sharing:sharing 
1029
                                                                          isPublic:isPublic 
1030
                                                                          metadata:metadata 
1031
                                                               sourceContainerName:sourceContainerName 
1032
                                                                  sourceObjectName:sourceObjectName 
1033
                                                                     sourceAccount:sourceAccount];
1034
    [request addRequestIfMatchHeader:matchETag];
1035
    return request;                                               
1036
}
1037

    
1038
// PUT storageURL/container/object (move from source) [If-None-Match]
1039
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1040
                                  objectName:(NSString *)objectName 
1041
                                 contentType:(NSString *)contentType 
1042
                             contentEncoding:(NSString *)contentEncoding 
1043
                          contentDisposition:(NSString *)contentDisposition 
1044
                                    manifest:(NSString *)manifest 
1045
                                     sharing:(NSString *)sharing 
1046
                                    isPublic:(NSUInteger)isPublic 
1047
                                    metadata:(NSDictionary *)metadata 
1048
                         sourceContainerName:(NSString *)sourceContainerName 
1049
                            sourceObjectName:(NSString *)sourceObjectName
1050
                               sourceAccount:(NSString *)sourceAccount
1051
                                 ifNoneMatch:(NSString *)matchETag {
1052
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1053
                                                                       contentType:contentType 
1054
                                                                   contentEncoding:contentEncoding 
1055
                                                                contentDisposition:contentDisposition 
1056
                                                                          manifest:manifest 
1057
                                                                           sharing:sharing 
1058
                                                                          isPublic:isPublic 
1059
                                                                          metadata:metadata 
1060
                                                               sourceContainerName:sourceContainerName 
1061
                                                                  sourceObjectName:sourceObjectName 
1062
                                                                     sourceAccount:sourceAccount];
1063
    [request addRequestIfNoneMatchHeader:matchETag];
1064
    return request;                                               
1065
}
1066

    
1067
// MOVE storageURL/container/object (move to destination)
1068
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1069
                                  objectName:(NSString *)objectName 
1070
                                 contentType:(NSString *)contentType 
1071
                             contentEncoding:(NSString *)contentEncoding 
1072
                          contentDisposition:(NSString *)contentDisposition 
1073
                                    manifest:(NSString *)manifest 
1074
                                     sharing:(NSString *)sharing 
1075
                                    isPublic:(NSUInteger)isPublic 
1076
                                    metadata:(NSDictionary *)metadata 
1077
                    destinationContainerName:(NSString *)destinationContainerName 
1078
                       destinationObjectName:(NSString *)destinationObjectName 
1079
                          destinationAccount:(NSString *)destinationAccount {
1080
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"MOVE" containerName:containerName objectName:objectName];
1081
    [request prepareObjectRequestWithETag:nil 
1082
                              contentType:contentType 
1083
                          contentEncoding:contentEncoding 
1084
                       contentDisposition:contentDisposition 
1085
                                 manifest:manifest 
1086
                                  sharing:sharing 
1087
                                 isPublic:isPublic 
1088
                                 metadata:metadata];
1089
    [request addRequestHeader:@"Destination" value:[NSString stringWithFormat:@"/%@/%@", destinationContainerName, destinationObjectName]];
1090
    if (destinationAccount)
1091
        [request addRequestHeader:@"Destination-Account" value:destinationAccount];
1092
    return request;
1093
}
1094

    
1095
// MOVE storageURL/container/object (move to destination) [If-Match]
1096
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1097
                                  objectName:(NSString *)objectName 
1098
                                 contentType:(NSString *)contentType 
1099
                             contentEncoding:(NSString *)contentEncoding 
1100
                          contentDisposition:(NSString *)contentDisposition 
1101
                                    manifest:(NSString *)manifest 
1102
                                     sharing:(NSString *)sharing 
1103
                                    isPublic:(NSUInteger)isPublic 
1104
                                    metadata:(NSDictionary *)metadata 
1105
                    destinationContainerName:(NSString *)destinationContainerName 
1106
                       destinationObjectName:(NSString *)destinationObjectName
1107
                          destinationAccount:(NSString *)destinationAccount
1108
                                     ifMatch:(NSString *)matchETag {
1109
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1110
                                                                       contentType:contentType 
1111
                                                                   contentEncoding:contentEncoding 
1112
                                                                contentDisposition:contentDisposition 
1113
                                                                          manifest:manifest 
1114
                                                                           sharing:sharing 
1115
                                                                          isPublic:isPublic 
1116
                                                                          metadata:metadata 
1117
                                                          destinationContainerName:destinationContainerName 
1118
                                                             destinationObjectName:destinationObjectName 
1119
                                                                destinationAccount:destinationAccount];
1120
    [request addRequestIfMatchHeader:matchETag];
1121
    return request;                                                                          
1122
}
1123

    
1124
// MOVE storageURL/container/object (move to destination) [If-None-Match]
1125
+ (id)moveObjectDataRequestWithContainerName:(NSString *)containerName 
1126
                                  objectName:(NSString *)objectName 
1127
                                 contentType:(NSString *)contentType 
1128
                             contentEncoding:(NSString *)contentEncoding 
1129
                          contentDisposition:(NSString *)contentDisposition 
1130
                                    manifest:(NSString *)manifest 
1131
                                     sharing:(NSString *)sharing 
1132
                                    isPublic:(NSUInteger)isPublic 
1133
                                    metadata:(NSDictionary *)metadata 
1134
                    destinationContainerName:(NSString *)destinationContainerName 
1135
                       destinationObjectName:(NSString *)destinationObjectName
1136
                          destinationAccount:(NSString *)destinationAccount
1137
                                 ifNoneMatch:(NSString *)matchETag {
1138
    ASIPithosObjectRequest *request = [self moveObjectDataRequestWithContainerName:containerName objectName:objectName 
1139
                                                                       contentType:contentType 
1140
                                                                   contentEncoding:contentEncoding 
1141
                                                                contentDisposition:contentDisposition 
1142
                                                                          manifest:manifest 
1143
                                                                           sharing:sharing 
1144
                                                                          isPublic:isPublic 
1145
                                                                          metadata:metadata 
1146
                                                          destinationContainerName:destinationContainerName 
1147
                                                             destinationObjectName:destinationObjectName 
1148
                                                                destinationAccount:destinationAccount];
1149
    [request addRequestIfNoneMatchHeader:matchETag];
1150
    return request;                                                                          
1151
}
1152

    
1153
#pragma mark -
1154
#pragma mark POST
1155

    
1156
// POST storageURL/container/object?[update=] (update metadata)
1157
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName update:(BOOL)update {
1158
    NSString *queryString = nil;
1159
    if (update)
1160
        queryString = @"?update=";
1161
	return [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1162
}
1163

    
1164
// POST storageURL/container/object?[update=] (update metadata) [If-Match]
1165
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1166
                                            update:(BOOL)update 
1167
                                           ifMatch:(NSString *)matchETag {
1168
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName update:update];
1169
    [request addRequestIfMatchHeader:matchETag];
1170
    return request;                                                                          
1171
}
1172

    
1173
// POST storageURL/container/object?[update=] (update metadata) [If-None-Match]
1174
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1175
                                            update:(BOOL)update 
1176
                                       ifNoneMatch:(NSString *)matchETag {
1177
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName update:update];
1178
    [request addRequestIfNoneMatchHeader:matchETag];
1179
    return request;                                                                          
1180
}
1181

    
1182
// POST storageURL/container/object?[update=] (update metadata)
1183
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1184
                                   contentEncoding:(NSString *)contentEncoding 
1185
                                contentDisposition:(NSString *)contentDisposition 
1186
                                          manifest:(NSString *)manifest 
1187
                                           sharing:(NSString *)sharing 
1188
                                          isPublic:(NSUInteger)isPublic 
1189
                                          metadata:(NSDictionary *)metadata 
1190
                                            update:(BOOL)update {
1191
    NSString *queryString = nil;
1192
    if (update)
1193
        queryString = @"?update=";
1194
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1195
    [request prepareObjectRequestWithETag:nil 
1196
                              contentType:nil 
1197
                          contentEncoding:contentEncoding 
1198
                       contentDisposition:contentDisposition 
1199
                                 manifest:manifest 
1200
                                  sharing:sharing 
1201
                                 isPublic:isPublic 
1202
                                 metadata:metadata];
1203
    return request;
1204
}
1205

    
1206
// POST storageURL/container/object?[update=] (update metadata) [If-Match]
1207
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1208
                                   contentEncoding:(NSString *)contentEncoding 
1209
                                contentDisposition:(NSString *)contentDisposition 
1210
                                          manifest:(NSString *)manifest 
1211
                                           sharing:(NSString *)sharing 
1212
                                          isPublic:(NSUInteger)isPublic 
1213
                                          metadata:(NSDictionary *)metadata 
1214
                                            update:(BOOL)update 
1215
                                           ifMatch:(NSString *)matchETag {
1216
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName 
1217
                                                                         contentEncoding:contentEncoding 
1218
                                                                      contentDisposition:contentDisposition 
1219
                                                                                manifest:manifest 
1220
                                                                                 sharing:sharing 
1221
                                                                                isPublic:isPublic 
1222
                                                                                metadata:metadata 
1223
                                                                                  update:update];
1224
    [request addRequestIfMatchHeader:matchETag];
1225
    return request;                                                                          
1226
}
1227

    
1228
// POST storageURL/container/object?[update=] (update metadata) [If-None-Match]
1229
+ (id)updateObjectMetadataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1230
                                   contentEncoding:(NSString *)contentEncoding 
1231
                                contentDisposition:(NSString *)contentDisposition 
1232
                                          manifest:(NSString *)manifest 
1233
                                           sharing:(NSString *)sharing 
1234
                                          isPublic:(NSUInteger)isPublic 
1235
                                          metadata:(NSDictionary *)metadata 
1236
                                            update:(BOOL)update 
1237
                                       ifNoneMatch:(NSString *)matchETag {
1238
    ASIPithosObjectRequest *request = [self updateObjectMetadataRequestWithContainerName:containerName objectName:objectName 
1239
                                                                         contentEncoding:contentEncoding 
1240
                                                                      contentDisposition:contentDisposition 
1241
                                                                                manifest:manifest 
1242
                                                                                 sharing:sharing 
1243
                                                                                isPublic:isPublic 
1244
                                                                                metadata:metadata 
1245
                                                                                  update:update];
1246
    [request addRequestIfNoneMatchHeader:matchETag];
1247
    return request;                                                                          
1248
}
1249

    
1250
// POST storageURL/container/object?[update=] (update data from ASIPithosObject with data)
1251
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object 
1252
                                        update:(BOOL)update 
1253
                                  contentRange:(NSString *)contentRange {
1254
    NSUInteger isPublic = ASIPithosObjectRequestPublicIgnore;
1255
    if (object.publicURI) {
1256
        isPublic = ASIPithosObjectRequestPublicTrue;
1257
        if ([object.publicURI isEqualToString:@""])
1258
            isPublic = ASIPithosObjectRequestPublicFalse;
1259
    }
1260
    return [self updateObjectDataRequestWithContainerName:containerName objectName:object.name 
1261
                                          contentEncoding:object.contentEncoding 
1262
                                       contentDisposition:object.contentDisposition 
1263
                                                 manifest:object.manifest 
1264
                                                  sharing:object.sharing 
1265
                                                 isPublic:isPublic
1266
                                                 metadata:object.metadata 
1267
                                                   update:update 
1268
                                             contentRange:contentRange 
1269
                                                    bytes:[NSNumber numberWithUnsignedLong:object.bytes]
1270
                                                    data:object.data];
1271
}
1272

    
1273
// POST storageURL/container/object?[update=] (update data from ASIPithosObject with data) [If-Match]
1274
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object 
1275
                                        update:(BOOL)update 
1276
                                  contentRange:(NSString *)contentRange 
1277
                                       ifMatch:(NSString *)matchETag {
1278
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName object:object 
1279
                                                                              update:update 
1280
                                                                        contentRange:contentRange];
1281
    [request addRequestIfMatchHeader:matchETag];
1282
    return request;                                                                          
1283
}
1284

    
1285
// POST storageURL/container/object?[update=] (update data from ASIPithosObject with data) [If-None-Match]
1286
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName object:(ASIPithosObject *)object 
1287
                                        update:(BOOL)update 
1288
                                  contentRange:(NSString *)contentRange 
1289
                                   ifNoneMatch:(NSString *)matchETag {
1290
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName object:object 
1291
                                                                              update:update 
1292
                                                                        contentRange:contentRange];
1293
    [request addRequestIfNoneMatchHeader:matchETag];
1294
    return request;                                                                          
1295
}
1296

    
1297
// POST storageURL/container/object?[update=] (update data from NSData)
1298
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1299
                               contentEncoding:(NSString *)contentEncoding 
1300
                            contentDisposition:(NSString *)contentDisposition 
1301
                                      manifest:(NSString *)manifest 
1302
                                       sharing:(NSString *)sharing 
1303
                                      isPublic:(NSUInteger)isPublic 
1304
                                      metadata:(NSDictionary *)metadata 
1305
                                        update:(BOOL)update 
1306
                                  contentRange:(NSString *)contentRange 
1307
                                         bytes:(NSNumber *)bytes 
1308
                                          data:(NSData *)data {
1309
    NSString *queryString = nil;
1310
    if (update)
1311
        queryString = @"?update=";
1312
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1313
    [request prepareObjectRequestWithETag:nil
1314
                              contentType:@"application/octet-stream"
1315
                          contentEncoding:contentEncoding 
1316
                       contentDisposition:contentDisposition 
1317
                                 manifest:manifest 
1318
                                  sharing:sharing 
1319
                                 isPublic:isPublic 
1320
                                 metadata:metadata];
1321
    if (contentRange)
1322
        [request addRequestHeader:@"Content-Range" value:contentRange];
1323
    if (bytes)
1324
        [request addRequestHeader:@"X-Object-Bytes" value:[NSString stringWithFormat:@"%lu", [bytes unsignedLongValue]]];
1325
	[request appendPostData:data];
1326
	return request;
1327
}
1328

    
1329
// POST storageURL/container/object?[update=] (update data from NSData) [If-Match]
1330
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1331
                               contentEncoding:(NSString *)contentEncoding 
1332
                            contentDisposition:(NSString *)contentDisposition 
1333
                                      manifest:(NSString *)manifest 
1334
                                       sharing:(NSString *)sharing 
1335
                                      isPublic:(NSUInteger)isPublic 
1336
                                      metadata:(NSDictionary *)metadata 
1337
                                        update:(BOOL)update 
1338
                                  contentRange:(NSString *)contentRange 
1339
                                         bytes:(NSNumber *)bytes 
1340
                                          data:(NSData *)data 
1341
                                       ifMatch:(NSString *)matchETag {
1342
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1343
                                                                     contentEncoding:contentEncoding 
1344
                                                                  contentDisposition:contentDisposition 
1345
                                                                            manifest:manifest 
1346
                                                                             sharing:sharing 
1347
                                                                            isPublic:isPublic 
1348
                                                                            metadata:metadata 
1349
                                                                              update:update 
1350
                                                                        contentRange:contentRange 
1351
                                                                               bytes:bytes 
1352
                                                                                data:data];
1353
    [request addRequestIfMatchHeader:matchETag];
1354
    return request;                                                                          
1355
}
1356

    
1357
// POST storageURL/container/object?[update=] (update data from NSData) [If-None-Match]
1358
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1359
                               contentEncoding:(NSString *)contentEncoding 
1360
                            contentDisposition:(NSString *)contentDisposition 
1361
                                      manifest:(NSString *)manifest 
1362
                                       sharing:(NSString *)sharing 
1363
                                      isPublic:(NSUInteger)isPublic 
1364
                                      metadata:(NSDictionary *)metadata 
1365
                                        update:(BOOL)update 
1366
                                  contentRange:(NSString *)contentRange 
1367
                                         bytes:(NSNumber *)bytes 
1368
                                          data:(NSData *)data 
1369
                                   ifNoneMatch:(NSString *)matchETag {
1370
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1371
                                                                     contentEncoding:contentEncoding 
1372
                                                                  contentDisposition:contentDisposition 
1373
                                                                            manifest:manifest 
1374
                                                                             sharing:sharing 
1375
                                                                            isPublic:isPublic 
1376
                                                                            metadata:metadata 
1377
                                                                              update:update 
1378
                                                                        contentRange:contentRange 
1379
                                                                               bytes:bytes 
1380
                                                                                data:data];
1381
    [request addRequestIfNoneMatchHeader:matchETag];
1382
    return request;                                                                          
1383
}
1384

    
1385
// POST storageURL/container/object?[update=] (update data from file)
1386
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1387
                               contentEncoding:(NSString *)contentEncoding 
1388
                            contentDisposition:(NSString *)contentDisposition 
1389
                                      manifest:(NSString *)manifest 
1390
                                       sharing:(NSString *)sharing 
1391
                                      isPublic:(NSUInteger)isPublic 
1392
                                      metadata:(NSDictionary *)metadata 
1393
                                        update:(BOOL)update 
1394
                                  contentRange:(NSString *)contentRange 
1395
                                         bytes:(NSNumber *)bytes 
1396
                                          file:(NSString *)filePath {
1397
    NSString *queryString = nil;
1398
    if (update)
1399
        queryString = @"?update=";
1400
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1401
    [request prepareObjectRequestWithETag:nil
1402
                              contentType:@"application/octet-stream"
1403
                          contentEncoding:contentEncoding 
1404
                       contentDisposition:contentDisposition 
1405
                                 manifest:manifest 
1406
                                  sharing:sharing 
1407
                                 isPublic:isPublic 
1408
                                 metadata:metadata];
1409
    if (contentRange)
1410
        [request addRequestHeader:@"Content-Range" value:contentRange];
1411
    if (bytes)
1412
        [request addRequestHeader:@"X-Object-Bytes" value:[NSString stringWithFormat:@"%lu", [bytes unsignedLongValue]]];
1413
	request.shouldStreamPostDataFromDisk = YES;
1414
    request.postBodyFilePath = filePath;
1415
	return request;
1416
}
1417

    
1418
// POST storageURL/container/object?[update=] (update data from file) [If-Match]
1419
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1420
                               contentEncoding:(NSString *)contentEncoding 
1421
                            contentDisposition:(NSString *)contentDisposition 
1422
                                      manifest:(NSString *)manifest 
1423
                                       sharing:(NSString *)sharing 
1424
                                      isPublic:(NSUInteger)isPublic 
1425
                                      metadata:(NSDictionary *)metadata 
1426
                                        update:(BOOL)update 
1427
                                  contentRange:(NSString *)contentRange 
1428
                                         bytes:(NSNumber *)bytes 
1429
                                          file:(NSString *)filePath 
1430
                                       ifMatch:(NSString *)matchETag {
1431
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1432
                                                                     contentEncoding:contentEncoding 
1433
                                                                  contentDisposition:contentDisposition 
1434
                                                                            manifest:manifest 
1435
                                                                             sharing:sharing 
1436
                                                                            isPublic:isPublic 
1437
                                                                            metadata:metadata 
1438
                                                                              update:update 
1439
                                                                        contentRange:contentRange 
1440
                                                                               bytes:bytes 
1441
                                                                                file:filePath];
1442
    [request addRequestIfMatchHeader:matchETag];
1443
    return request;                                                                          
1444
}
1445

    
1446
// POST storageURL/container/object?[update=] (update data from file) [If-None-Match]
1447
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1448
                               contentEncoding:(NSString *)contentEncoding 
1449
                            contentDisposition:(NSString *)contentDisposition 
1450
                                      manifest:(NSString *)manifest 
1451
                                       sharing:(NSString *)sharing 
1452
                                      isPublic:(NSUInteger)isPublic 
1453
                                      metadata:(NSDictionary *)metadata 
1454
                                        update:(BOOL)update 
1455
                                  contentRange:(NSString *)contentRange 
1456
                                         bytes:(NSNumber *)bytes 
1457
                                          file:(NSString *)filePath 
1458
                                   ifNoneMatch:(NSString *)matchETag {
1459
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1460
                                                                     contentEncoding:contentEncoding 
1461
                                                                  contentDisposition:contentDisposition 
1462
                                                                            manifest:manifest 
1463
                                                                             sharing:sharing 
1464
                                                                            isPublic:isPublic 
1465
                                                                            metadata:metadata 
1466
                                                                              update:update 
1467
                                                                        contentRange:contentRange 
1468
                                                                               bytes:bytes 
1469
                                                                                file:filePath];
1470
    [request addRequestIfNoneMatchHeader:matchETag];
1471
    return request;                                                                          
1472
}
1473

    
1474
// POST storageURL/container/object?[update=] (update data from source)
1475
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1476
                               contentEncoding:(NSString *)contentEncoding 
1477
                            contentDisposition:(NSString *)contentDisposition 
1478
                                      manifest:(NSString *)manifest 
1479
                                       sharing:(NSString *)sharing 
1480
                                      isPublic:(NSUInteger)isPublic 
1481
                                      metadata:(NSDictionary *)metadata 
1482
                                        update:(BOOL)update 
1483
                                  contentRange:(NSString *)contentRange 
1484
                                         bytes:(NSNumber *)bytes 
1485
                           sourceContainerName:(NSString *)sourceContainerName 
1486
                              sourceObjectName:(NSString *)sourceObjectName 
1487
                                 sourceVersion:(NSString *)sourceVersion {
1488
    NSString *queryString = nil;
1489
    if (update)
1490
        queryString = @"?update=";
1491
	ASIPithosObjectRequest *request = [self storageRequestWithMethod:@"POST" containerName:containerName objectName:objectName queryString:queryString];
1492
    [request prepareObjectRequestWithETag:nil
1493
                              contentType:nil
1494
                          contentEncoding:contentEncoding 
1495
                       contentDisposition:contentDisposition 
1496
                                 manifest:manifest 
1497
                                  sharing:sharing 
1498
                                 isPublic:isPublic 
1499
                                 metadata:metadata];
1500
    if (contentRange)
1501
        [request addRequestHeader:@"Content-Range" value:contentRange];
1502
    if (bytes)
1503
        [request addRequestHeader:@"X-Object-Bytes" value:[NSString stringWithFormat:@"%lu", [bytes unsignedLongValue]]];
1504
    [request addRequestHeader:@"X-Source-Object" value:[NSString stringWithFormat:@"/%@/%@", sourceContainerName, sourceObjectName]];
1505
    if (sourceVersion)
1506
        [request addRequestHeader:@"X-Source-Version" value:sourceVersion];
1507
	return request;
1508

    
1509
}
1510

    
1511
// POST storageURL/container/object?[update=] (update data from source) [If-Match]
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
                                 sourceVersion:(NSString *)sourceVersion 
1525
                                       ifMatch:(NSString *)matchETag {
1526
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1527
                                                                     contentEncoding:contentEncoding 
1528
                                                                  contentDisposition:contentDisposition 
1529
                                                                            manifest:manifest 
1530
                                                                             sharing:sharing 
1531
                                                                            isPublic:isPublic 
1532
                                                                            metadata:metadata 
1533
                                                                              update:update 
1534
                                                                        contentRange:contentRange 
1535
                                                                               bytes:bytes 
1536
                                                                 sourceContainerName:sourceContainerName 
1537
                                                                    sourceObjectName:sourceObjectName 
1538
                                                                       sourceVersion:sourceVersion];
1539
    [request addRequestIfMatchHeader:matchETag];
1540
    return request;                                                                          
1541
}
1542

    
1543
// POST storageURL/container/object?[update=] (update data from source) [If-None-Match]
1544
+ (id)updateObjectDataRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName 
1545
                               contentEncoding:(NSString *)contentEncoding 
1546
                            contentDisposition:(NSString *)contentDisposition 
1547
                                      manifest:(NSString *)manifest 
1548
                                       sharing:(NSString *)sharing 
1549
                                      isPublic:(NSUInteger)isPublic 
1550
                                      metadata:(NSDictionary *)metadata 
1551
                                        update:(BOOL)update 
1552
                                  contentRange:(NSString *)contentRange 
1553
                                         bytes:(NSNumber *)bytes 
1554
                           sourceContainerName:(NSString *)sourceContainerName 
1555
                              sourceObjectName:(NSString *)sourceObjectName 
1556
                                 sourceVersion:(NSString *)sourceVersion 
1557
                                   ifNoneMatch:(NSString *)matchETag {
1558
    ASIPithosObjectRequest *request = [self updateObjectDataRequestWithContainerName:containerName objectName:objectName 
1559
                                                                     contentEncoding:contentEncoding 
1560
                                                                  contentDisposition:contentDisposition 
1561
                                                                            manifest:manifest 
1562
                                                                             sharing:sharing 
1563
                                                                            isPublic:isPublic 
1564
                                                                            metadata:metadata 
1565
                                                                              update:update 
1566
                                                                        contentRange:contentRange 
1567
                                                                               bytes:bytes 
1568
                                                                 sourceContainerName:sourceContainerName 
1569
                                                                    sourceObjectName:sourceObjectName 
1570
                                                                       sourceVersion:sourceVersion];
1571
    [request addRequestIfNoneMatchHeader:matchETag];
1572
    return request;                                                                          
1573
}
1574

    
1575
#pragma mark -
1576
#pragma mark DELETE
1577

    
1578
// DELETE storageURL/container/object
1579
+ (id)deleteObjectRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName {
1580
    return [self storageRequestWithMethod:@"DELETE" containerName:containerName objectName:objectName];
1581
}
1582

    
1583
// DELETE storageURL/container/object?[until=untilTimestamp]
1584
+ (id)deleteObjectRequestWithContainerName:(NSString *)containerName objectName:(NSString *)objectName until:(NSDate *)untilTimestamp {
1585
    NSString *queryString = nil;
1586
    if (untilTimestamp)
1587
        queryString = [NSString stringWithFormat:@"?until=%d", (int)[untilTimestamp timeIntervalSince1970]];
1588
	return [self storageRequestWithMethod:@"DELETE" containerName:containerName objectName:objectName queryString:queryString];
1589
}
1590

    
1591
#pragma mark -
1592
#pragma mark NSXMLParserDelegate
1593

    
1594
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
1595
	self.currentElement = elementName;
1596
    if ((objectRequestType == ASIPithosObjectRequestHashmap) && [elementName isEqualToString:@"object"]) {
1597
        blockSize = [[attributeDict valueForKey:@"block_size"] intValue];
1598
        blockHash = [[NSString alloc] initWithString:[attributeDict valueForKey:@"block_hash"]];
1599
        bytes = [[attributeDict valueForKey:@"bytes"] intValue];
1600
    } else if ((objectRequestType == ASIPithosObjectRequestVersions) && [elementName isEqualToString:@"version"]) {
1601
        self.currentObject = [ASIPithosObject object];
1602
        currentObject.versionTimestamp = [NSDate dateWithTimeIntervalSince1970:[[attributeDict valueForKey:@"timestamp"] intValue]];
1603
	}
1604
	self.currentContent = @"";
1605
}
1606

    
1607
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
1608
	if ((objectRequestType == ASIPithosObjectRequestHashmap) && [elementName isEqualToString:@"hash"]) {
1609
        [hashes addObject:currentContent];
1610
    } else if (objectRequestType == ASIPithosObjectRequestVersions) {
1611
        if ([elementName isEqualToString:@"version"]) {
1612
            currentObject.version = currentContent;
1613
        } else if ([elementName isEqualToString:@"object"]) {
1614
            [versions addObject:currentObject];
1615
            self.currentObject = nil;
1616
        }
1617
	}
1618
}
1619

    
1620
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
1621
    self.currentContent = [currentContent stringByAppendingString:string];
1622
}
1623

    
1624
@end