Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Classes / Pithos / ASIPithosContainerRequest.m @ 2f816d2a

History | View | Annotate | Download (22.5 kB)

1
//  ASIPithosContainerRequest.m
2
//  Based on ASICloudFilesContainerRequest.m
3
//
4
// Copyright 2011-2012 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 "ASIPithosContainerRequest.h"
38
#import "ASIPithos.h"
39
#import "ASIPithosContainer.h"
40
#import "ASIPithosObject.h"
41

    
42
@implementation ASIPithosContainerRequest
43
@synthesize containerName;
44
@synthesize currentObject, currentKey;
45

    
46
#pragma mark -
47
#pragma mark Constructors
48

    
49
+ (id)storageRequestWithMethod:(NSString *)method 
50
                        pithos:(ASIPithos *)pithos 
51
                 containerName:(NSString *)containerName 
52
                   queryString:(NSString *)queryString {
53
    NSString *urlString = [NSString stringWithFormat:@"%@/%@", pithos.storageURL, [self encodeToPercentEscape:containerName]];
54
    if (queryString)
55
        urlString = [urlString stringByAppendingString:queryString];
56

    
57
	ASIPithosContainerRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:urlString]] autorelease];
58
	[request setRequestMethod:method];
59
	[request addRequestHeader:@"X-Auth-Token" value:pithos.authToken];
60
    request.containerName = containerName;
61
	return request;
62
}
63

    
64
+ (id)storageRequestWithMethod:(NSString *)method pithos:(ASIPithos *)pithos containerName:(NSString *)containerName {
65
	return [self storageRequestWithMethod:method pithos:pithos containerName:containerName queryString:nil];
66
}
67

    
68
#pragma mark -
69
#pragma mark Memory Management
70

    
71
- (void)dealloc {
72
    [currentKey release];
73
	[currentObject release];
74
    [objects release];
75
    [metadata release];
76
    [policy release];
77
    [containerName release];
78
	[super dealloc];
79
}
80

    
81
#pragma mark -
82
#pragma mark HEAD
83

    
84
// HEAD storageURL/container
85
+ (id)containerMetadataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName {
86
    return [self storageRequestWithMethod:@"HEAD" pithos:pithos containerName:containerName];
87
}
88

    
89
// HEAD storageURL/container?[until=untilTimestamp]
90
+ (id)containerMetadataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName until:(NSDate *)untilTimestamp {
91
    NSString *queryString = nil;
92
    if (untilTimestamp)
93
        queryString = [NSString stringWithFormat:@"?until=%d", (int)[untilTimestamp timeIntervalSince1970]];
94
    
95
	return [self storageRequestWithMethod:@"HEAD" pithos:pithos containerName:containerName queryString:queryString];
96
}
97

    
98
// HEAD storageURL/container?[until=untilTimestamp] [If-Modified-Since]
99
+ (id)containerMetadataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName 
100
                                   until:(NSDate *)untilTimestamp 
101
                         ifModifiedSince:(NSDate *)sinceTimestamp {
102
    ASIPithosContainerRequest *request = [self containerMetadataRequestWithPithos:pithos containerName:containerName until:untilTimestamp];
103
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
104
    return request;
105
}
106

    
107
// HEAD storageURL/container?[until=untilTimestamp] [If-Unmodified-Since]
108
+ (id)containerMetadataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName 
109
                                   until:(NSDate *)untilTimestamp 
110
                       ifUnmodifiedSince:(NSDate *)sinceTimestamp {
111
    ASIPithosContainerRequest *request = [self containerMetadataRequestWithPithos:pithos containerName:containerName until:untilTimestamp];
112
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
113
    return request;
114
}
115

    
116
- (NSUInteger)objectCount {
117
	return [[[self responseHeaders] objectForKey:@"X-Container-Object-Count"] intValue];
118
}
119

    
120
- (NSUInteger)bytesUsed {
121
	return [[[self responseHeaders] objectForKey:@"X-Container-Bytes-Used"] intValue];
122
}
123

    
124
- (NSUInteger)blockSize {
125
	return [[[self responseHeaders] objectForKey:@"X-Container-Block-Size"] intValue];
126
}
127

    
128
- (NSString *)blockHash {
129
	return [[self responseHeaders] objectForKey:@"X-Container-Block-Hash"];
130
}
131

    
132
- (NSArray *)objectMeta {
133
    return [[self decodeFromPercentEscape:[[self responseHeaders] objectForKey:@"X-Container-Object-Meta"]] 
134
            componentsSeparatedByString:@","];
135
}
136

    
137
- (NSDate *)untilTimestamp {
138
    NSString *untilTimestampString = [[self responseHeaders] objectForKey:@"X-Container-Until-Timestamp"];
139
    if (untilTimestampString)
140
        return [[self dateFormatterWithFormatId:1] dateFromString:untilTimestampString];
141
    return nil;
142
}
143

    
144
- (NSDictionary *)policy {
145
    if (policy == nil) {
146
        policy = [self getHeadersDictionaryForPrefix:@"X-Container-Policy-"];
147
        [policy retain];
148
    }
149
    return policy;
150
}
151

    
152
- (NSDictionary *)metadata {
153
    if (metadata == nil) {
154
        metadata = [self getHeadersDictionaryForPrefix:@"X-Container-Meta-"];
155
        [metadata retain];
156
    }
157
    return metadata;
158
}
159

    
160
- (NSDate *)lastModified {
161
    NSString *lastModifiedString = [[self responseHeaders] objectForKey:@"Last-Modified"];
162
    if (lastModifiedString)
163
        return [[self dateFormatterWithFormatId:1] dateFromString:lastModifiedString];
164
    return nil;
165
}
166

    
167
- (ASIPithosContainer *)container {
168
    ASIPithosContainer *container = [ASIPithosContainer container];
169
    container.name = containerName;
170
    container.count = [self objectCount];
171
    container.bytes = [self bytesUsed];
172
    container.lastModified = [self lastModified];
173
    container.untilTimestamp = [self untilTimestamp];
174
    container.policy = (NSMutableDictionary *)[self policy];
175
    container.metadata = (NSMutableDictionary *)[self metadata];
176
    container.blockSize =  [self blockSize];
177
    container.blockHash =  [self blockHash];
178
    container.objectMeta = (NSMutableArray *)[self objectMeta];
179
    return container;
180
}
181

    
182
#pragma mark -
183
#pragma mark GET
184

    
185
// GET storageURL/container
186
+ (id)listObjectsRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName {
187
    return [self storageRequestWithMethod:@"GET" pithos:pithos containerName:containerName queryString:@"?format=xml"];
188
}
189

    
190
// GET storageURL?[limit=limit]&[marker=marker]&[prefix=prefix]&[delimiter=delimiter]&[path=path]&[meta=meta]&[shared=]&[until=untilTimestamp]
191
+ (id)listObjectsRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName
192
                             limit:(NSUInteger)limit 
193
                            marker:(NSString *)marker 
194
                            prefix:(NSString *)prefix 
195
                         delimiter:(NSString *)delimiter 
196
                              path:(NSString *)path 
197
                              meta:(NSArray *)meta 
198
                            shared:(BOOL)shared
199
                             until:(NSDate *)untilTimestamp {
200
    NSString *queryString = @"?format=xml";
201
	if (limit && (limit > 0))
202
		queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&limit=%lu", limit]];
203
	if (marker)
204
		queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&marker=%@", [self encodeToPercentEscape:marker]]];
205
	if (prefix)
206
		queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&prefix=%@", [self encodeToPercentEscape:prefix]]];
207
	if (delimiter)
208
		queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&delimiter=%@", [self encodeToPercentEscape:delimiter]]];
209
	if (path)
210
		queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&path=%@", [self encodeToPercentEscape:path]]];
211
    if (meta)
212
        queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&meta=%@", [self encodeToPercentEscape:[meta componentsJoinedByString:@","]]]];
213
	if (shared)
214
		queryString = [queryString stringByAppendingString:@"&shared="];
215
    if (untilTimestamp)
216
        queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&until=%d", (int)[untilTimestamp timeIntervalSince1970]]];
217
    
218
    return [self storageRequestWithMethod:@"GET" pithos:pithos containerName:containerName queryString:queryString];
219
}
220

    
221
// GET storageURL?[limit=limit]&[marker=marker]&[prefix=prefix]&[delimiter=delimiter]&[path=path]&[meta=meta]&[shared=]&[until=untilTimestamp] [If-Modified-Since]
222
+ (id)listObjectsRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName
223
                             limit:(NSUInteger)limit 
224
                            marker:(NSString *)marker 
225
                            prefix:(NSString *)prefix 
226
                         delimiter:(NSString *)delimiter 
227
                              path:(NSString *)path 
228
                              meta:(NSArray *)meta 
229
                            shared:(BOOL)shared
230
                             until:(NSDate *)untilTimestamp 
231
                   ifModifiedSince:(NSDate *)sinceTimestamp {
232
    ASIPithosContainerRequest *request = [self listObjectsRequestWithPithos:pithos 
233
                                                              containerName:containerName 
234
                                                                      limit:limit 
235
                                                                     marker:marker 
236
                                                                     prefix:prefix 
237
                                                                  delimiter:delimiter 
238
                                                                       path:path 
239
                                                                       meta:meta 
240
                                                                     shared:shared 
241
                                                                      until:untilTimestamp];
242
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
243
    return request;
244
}
245

    
246
// GET storageURL?[limit=limit]&[marker=marker]&[prefix=prefix]&[delimiter=delimiter]&[path=path]&[meta=meta]&[shared=]&[until=untilTimestamp] [If-Unmodified-Since]
247
+ (id)listObjectsRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName
248
                             limit:(NSUInteger)limit 
249
                            marker:(NSString *)marker 
250
                            prefix:(NSString *)prefix 
251
                         delimiter:(NSString *)delimiter 
252
                              path:(NSString *)path 
253
                              meta:(NSArray *)meta 
254
                            shared:(BOOL)shared
255
                             until:(NSDate *)untilTimestamp 
256
                 ifUnmodifiedSince:(NSDate *)sinceTimestamp {
257
    ASIPithosContainerRequest *request = [self listObjectsRequestWithPithos:pithos 
258
                                                              containerName:containerName 
259
                                                                      limit:limit 
260
                                                                     marker:marker 
261
                                                                     prefix:prefix 
262
                                                                  delimiter:delimiter 
263
                                                                       path:path 
264
                                                                       meta:meta 
265
                                                                     shared:shared 
266
                                                                      until:untilTimestamp];
267
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
268
    return request;
269
}
270

    
271

    
272
- (NSArray *)objects {
273
    if (objects == nil) {
274
        objects = [[NSMutableArray alloc] init];
275
        
276
        NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease];
277
        [parser setDelegate:self];
278
        [parser setShouldProcessNamespaces:NO];
279
        [parser setShouldReportNamespacePrefixes:NO];
280
        [parser setShouldResolveExternalEntities:NO];
281
        [parser parse];
282
    }    
283
	return objects;
284
}
285

    
286
#pragma mark -
287
#pragma mark PUT
288

    
289
// PUT storageURL/container
290
+ (id)createOrUpdateContainerRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName {
291
    return [self storageRequestWithMethod:@"PUT" pithos:pithos containerName:containerName];
292
}
293

    
294
// PUT storageURL/container [X-Container-Policy-*] [X-Container-Meta-*]
295
+ (id)createOrUpdateContainerRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName 
296
                                        policy:(NSDictionary *)policy 
297
                                      metadata:(NSDictionary *)metadata {
298
    ASIPithosContainerRequest *request = [self storageRequestWithMethod:@"PUT" pithos:pithos containerName:containerName];
299
	
300
    if (policy) {
301
        for (NSString *key in [policy keyEnumerator]) {
302
            [request addRequestHeader:[NSString stringWithFormat:@"X-Container-Policy-%@", key] value:[policy objectForKey:key]];
303
        }
304
    }
305
    
306
    if (metadata) {
307
        for (NSString *key in [metadata keyEnumerator]) {
308
            [request addRequestHeader:[self encodeToPercentEscape:[NSString stringWithFormat:@"X-Container-Meta-%@", key]] 
309
                                value:[self encodeToPercentEscape:[metadata objectForKey:key]]];
310
        }
311
    }
312
    
313
	return request;
314
}
315

    
316
#pragma mark -
317
#pragma mark POST
318

    
319
// POST storageURL/container
320
+ (id)updateContainerMetadataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName {
321
    return [self storageRequestWithMethod:@"POST" pithos:pithos containerName:containerName];
322
}
323

    
324
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*]
325
+ (id)updateContainerMetadataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName 
326
                                        policy:(NSDictionary *)policy 
327
                                      metadata:(NSDictionary *)metadata 
328
                                        update:(BOOL)update {
329
    NSString *queryString = nil;
330
    if (update)
331
        queryString = @"?update=";
332
    ASIPithosContainerRequest *request = [self storageRequestWithMethod:@"POST" 
333
                                                                 pithos:pithos 
334
                                                          containerName:containerName 
335
                                                            queryString:queryString];
336
    if (policy) {
337
        for (NSString *key in [policy keyEnumerator]) {
338
            [request addRequestHeader:[NSString stringWithFormat:@"X-Container-Policy-%@", key] value:[policy objectForKey:key]];
339
        }
340
    }
341
    
342
    if (metadata) {
343
        for (NSString *key in [metadata keyEnumerator]) {
344
            [request addRequestHeader:[self encodeToPercentEscape:[NSString stringWithFormat:@"X-Container-Meta-%@", key]] 
345
                                value:[self encodeToPercentEscape:[metadata objectForKey:key]]];
346
        }
347
    }
348
    
349
	return request;
350
}
351

    
352
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*] (update data from ASIPithosObject with data)
353
+ (id)updateContainerDataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName 
354
                                    policy:(NSDictionary *)policy 
355
                                  metadata:(NSDictionary *)metadata 
356
                                    update:(BOOL)update
357
                                    object:(ASIPithosObject *)object {
358
    return [self updateContainerDataRequestWithPithos:pithos 
359
                                        containerName:containerName 
360
                                               policy:policy 
361
                                             metadata:metadata 
362
                                               update:update 
363
                                                 data:object.data];
364
}
365

    
366
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*] (update data from NSData)
367
+ (id)updateContainerDataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName 
368
                                    policy:(NSDictionary *)policy 
369
                                  metadata:(NSDictionary *)metadata 
370
                                    update:(BOOL)update
371
                                      data:(NSData *)data {
372
    ASIPithosContainerRequest *request = [self updateContainerMetadataRequestWithPithos:pithos 
373
                                                                          containerName:containerName 
374
                                                                                 policy:policy 
375
                                                                               metadata:metadata 
376
                                                                                 update:update];    
377
    [request addRequestHeader:@"Content-Type" value:@"application/octet-stream"];
378
	[request appendPostData:data];
379
	return request;
380
}
381

    
382
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*] (update data from file)
383
+ (id)updateContainerDataRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName 
384
                                    policy:(NSDictionary *)policy 
385
                                  metadata:(NSDictionary *)metadata 
386
                                    update:(BOOL)update
387
                                      file:(NSString *)filePath {
388
    ASIPithosContainerRequest *request = [self updateContainerMetadataRequestWithPithos:pithos 
389
                                                                          containerName:containerName 
390
                                                                                 policy:policy 
391
                                                                               metadata:metadata 
392
                                                                                 update:update];    
393
    [request addRequestHeader:@"Content-Type" value:@"application/octet-stream"];
394
	request.shouldStreamPostDataFromDisk = YES;
395
    request.postBodyFilePath = filePath;
396
	return request;
397
}
398

    
399
#pragma mark -
400
#pragma mark DELETE
401

    
402
// DELETE storageURL/container
403
+ (id)deleteContainerRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName {
404
    return [self storageRequestWithMethod:@"DELETE" pithos:pithos containerName:containerName];
405
}
406

    
407
// DELETE storageURL/container?[until=untilTimestamp]
408
+ (id)deleteContainerRequestWithPithos:(ASIPithos *)pithos containerName:(NSString *)containerName until:(NSDate *)untilTimestamp {
409
    NSString *queryString = nil;
410
    if (untilTimestamp)
411
        queryString = [NSString stringWithFormat:@"?until=%d", (int)[untilTimestamp timeIntervalSince1970]];
412
	return [self storageRequestWithMethod:@"DELETE" pithos:pithos containerName:containerName queryString:queryString];    
413
}
414

    
415
#pragma mark -
416
#pragma mark NSXMLParserDelegate
417

    
418
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
419
	self.currentElement = elementName;
420
	if ([elementName isEqualToString:@"object"]) {
421
		self.currentObject = [ASIPithosObject object];
422
	} else if ([elementName isEqualToString:@"subdir"]) {
423
		[objects addObject:[ASIPithosObject subdirWithName:[attributeDict valueForKey:@"name"]]];
424
	}
425

    
426
	self.currentContent = @"";
427
}
428

    
429
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
430
	if ([elementName isEqualToString:@"name"]) {
431
        currentObject.name = currentContent;
432
	} else if ([elementName isEqualToString:@"hash"]) {
433
        currentObject.hash = currentContent;
434
	} else if ([elementName isEqualToString:@"x_object_hash"]) {
435
        currentObject.objectHash = currentContent;
436
	} else if ([elementName isEqualToString:@"x_object_uuid"]) {
437
        currentObject.UUID = currentContent;
438
	} else if ([elementName isEqualToString:@"bytes"]) {
439
        currentObject.bytes = [currentContent intValue];
440
	} else if ([elementName isEqualToString:@"content_type"]) {
441
        currentObject.contentType = currentContent;
442
    } else if ([elementName isEqualToString:@"last_modified"]) {
443
        currentObject.lastModified = [[self dateFormatterWithFormatId:0] dateFromString:
444
         [currentContent stringByReplacingOccurrencesOfString:@":" 
445
                                                   withString:@"" 
446
                                                      options:NSBackwardsSearch 
447
                                                        range:NSMakeRange(([currentContent length] - 3), 1)]];
448
	} else if ([elementName isEqualToString:@"x_object_version"]) {
449
        currentObject.version = currentContent;
450
    } else if ([elementName isEqualToString:@"x_object_version_timestamp"]) {
451
        currentObject.versionTimestamp = [NSDate dateWithTimeIntervalSince1970:[currentContent doubleValue]];
452
	} else if ([elementName isEqualToString:@"x_object_modified_by"]) {
453
        currentObject.modifiedBy = currentContent;
454
	} else if ([elementName isEqualToString:@"x_object_sharing"]) {
455
        currentObject.sharing = currentContent;
456
	} else if ([elementName isEqualToString:@"x_object_shared_by"]) {
457
        currentObject.sharedBy = currentContent;
458
	} else if ([elementName isEqualToString:@"x_object_public"]) {
459
        currentObject.publicURI = currentContent;
460
	} else if ([elementName isEqualToString:@"x_object_allowed_to"]) {
461
        currentObject.allowedTo = currentContent;
462
	} else if ([elementName isEqualToString:@"object"]) {
463
		[objects addObject:currentObject];
464
        self.currentObject = nil;
465
	}
466
}
467

    
468
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
469
    self.currentContent = [currentContent stringByAppendingString:string];
470
}
471
    
472
@end