Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (22.5 kB)

1
//  ASIPithosContainerRequest.m
2
//  Based on ASICloudFilesContainerRequest.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 "ASIPithosContainerRequest.h"
38
#import "ASIPithosContainer.h"
39
#import "ASIPithosObject.h"
40

    
41
@implementation ASIPithosContainerRequest
42
@synthesize containerName;
43
@synthesize currentObject;
44

    
45
#pragma mark -
46
#pragma mark Constructors
47

    
48
+ (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName queryString:(NSString *)queryString {
49
    NSString *urlString = [NSString stringWithFormat:@"%@/%@", 
50
                           [self storageURL], 
51
                           [containerName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
52
    if (queryString)
53
        urlString = [urlString stringByAppendingString:queryString];
54

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

    
62
+ (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName {
63
	return [self storageRequestWithMethod:method containerName:containerName queryString:nil];
64
}
65

    
66
#pragma mark -
67
#pragma mark Memory Management
68

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

    
78
#pragma mark -
79
#pragma mark HEAD
80

    
81
// HEAD storageURL/container
82
+ (id)containerMetadataRequestWithContainerName:(NSString *)containerName {
83
    return [self storageRequestWithMethod:@"HEAD" containerName:containerName];
84
}
85

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

    
95
// HEAD storageURL/container?[until=untilTimestamp] [If-Modified-Since]
96
+ (id)containerMetadataRequestWithContainerName:(NSString *)containerName 
97
                                          until:(NSDate *)untilTimestamp 
98
                                ifModifiedSince:(NSDate *)sinceTimestamp {
99
    ASIPithosContainerRequest *request = [self containerMetadataRequestWithContainerName:containerName until:untilTimestamp];
100
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
101
    return request;
102
}
103

    
104
// HEAD storageURL/container?[until=untilTimestamp] [If-Unmodified-Since]
105
+ (id)containerMetadataRequestWithContainerName:(NSString *)containerName 
106
                                          until:(NSDate *)untilTimestamp 
107
                              ifUnmodifiedSince:(NSDate *)sinceTimestamp {
108
    ASIPithosContainerRequest *request = [self containerMetadataRequestWithContainerName:containerName until:untilTimestamp];
109
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
110
    return request;
111
}
112

    
113
- (NSUInteger)objectCount {
114
	return [[[self responseHeaders] objectForKey:@"X-Container-Object-Count"] intValue];
115
}
116

    
117
- (NSUInteger)bytesUsed {
118
	return [[[self responseHeaders] objectForKey:@"X-Container-Bytes-Used"] intValue];
119
}
120

    
121
- (NSUInteger)blockSize {
122
	return [[[self responseHeaders] objectForKey:@"X-Container-Block-Size"] intValue];
123
}
124

    
125
- (NSString *)blockHash {
126
	return [[self responseHeaders] objectForKey:@"X-Container-Block-Hash"];
127
}
128

    
129
- (NSArray *)objectMeta {
130
    return [[[[self responseHeaders] objectForKey:@"X-Container-Object-Meta"] 
131
             stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] 
132
            componentsSeparatedByString:@","];
133
}
134

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

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

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

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

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

    
180
#pragma mark -
181
#pragma mark GET
182

    
183
// GET storageURL/container
184
+ (id)listObjectsRequestWithContainerName:(NSString *)containerName {
185
    return [self storageRequestWithMethod:@"GET" containerName:containerName queryString:@"?format=xml"];
186
}
187

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

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

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

    
267

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

    
282
#pragma mark -
283
#pragma mark PUT
284

    
285
// PUT storageURL/container
286
+ (id)createOrUpdateContainerRequestWithContainerName:(NSString *)containerName {
287
    return [self storageRequestWithMethod:@"PUT" containerName:containerName];
288
}
289

    
290
// PUT storageURL/container [X-Container-Policy-*] [X-Container-Meta-*]
291
+ (id)createOrUpdateContainerRequestWithContainerName:(NSString *)containerName policy:(NSDictionary *)policy metadata:(NSDictionary *)metadata {
292
    ASIPithosContainerRequest *request = [self storageRequestWithMethod:@"PUT" containerName:containerName];
293
	
294
    if (policy) {
295
        for (NSString *key in [policy keyEnumerator]) {
296
            [request addRequestHeader:[NSString stringWithFormat:@"X-Container-Policy-%@", key] value:[policy objectForKey:key]];
297
        }
298
    }
299
    
300
    if (metadata) {
301
        for (NSString *key in [metadata keyEnumerator]) {
302
            [request addRequestHeader:[[NSString stringWithFormat:@"X-Container-Meta-%@", key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] 
303
                                value:[[metadata objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
304
        }
305
    }
306
    
307
	return request;
308
}
309

    
310
#pragma mark -
311
#pragma mark POST
312

    
313
// POST storageURL/container
314
+ (id)updateContainerMetadataRequestWithContainerName:(NSString *)containerName {
315
    return [self storageRequestWithMethod:@"POST" containerName:containerName];
316
}
317

    
318
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*]
319
+ (id)updateContainerMetadataRequestWithContainerName:(NSString *)containerName 
320
                                               policy:(NSDictionary *)policy 
321
                                             metadata:(NSDictionary *)metadata 
322
                                               update:(BOOL)update {
323
    NSString *queryString = nil;
324
    if (update)
325
        queryString = @"?update=";
326
    ASIPithosContainerRequest *request = [self storageRequestWithMethod:@"POST" 
327
                                                                               containerName:containerName
328
                                                                                 queryString:queryString];
329
    if (policy) {
330
        for (NSString *key in [policy keyEnumerator]) {
331
            [request addRequestHeader:[NSString stringWithFormat:@"X-Container-Policy-%@", key] value:[policy objectForKey:key]];
332
        }
333
    }
334
    
335
    if (metadata) {
336
        for (NSString *key in [metadata keyEnumerator]) {
337
            [request addRequestHeader:[[NSString stringWithFormat:@"X-Container-Meta-%@", key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] 
338
                                value:[[metadata objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
339
        }
340
    }
341
    
342
	return request;
343
}
344

    
345
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*] (update data from ASIPithosObject with data)
346
+ (id)updateContainerDataRequestWithContainerName:(NSString *)containerName 
347
                                           policy:(NSDictionary *)policy 
348
                                         metadata:(NSDictionary *)metadata 
349
                                           update:(BOOL)update
350
                                           object:(ASIPithosObject *)object {
351
    return [self updateContainerDataRequestWithContainerName:containerName 
352
                                                      policy:policy 
353
                                                    metadata:metadata 
354
                                                      update:update 
355
                                                        data:object.data];
356
}
357

    
358
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*] (update data from NSData)
359
+ (id)updateContainerDataRequestWithContainerName:(NSString *)containerName 
360
                                           policy:(NSDictionary *)policy 
361
                                         metadata:(NSDictionary *)metadata 
362
                                           update:(BOOL)update
363
                                             data:(NSData *)data {
364
    ASIPithosContainerRequest *request = [self updateContainerMetadataRequestWithContainerName:containerName 
365
                                                                                        policy:policy 
366
                                                                                      metadata:metadata 
367
                                                                                        update:update];    
368
    [request addRequestHeader:@"Content-Type" value:@"application/octet-stream"];
369
	[request appendPostData:data];
370
	return request;
371
}
372

    
373
// POST storageURL/container?[update=] [X-Container-Policy-*] [X-Container-Meta-*] (update data from file)
374
+ (id)updateContainerDataRequestWithContainerName:(NSString *)containerName 
375
                                           policy:(NSDictionary *)policy 
376
                                         metadata:(NSDictionary *)metadata 
377
                                           update:(BOOL)update
378
                                             file:(NSString *)filePath {
379
    ASIPithosContainerRequest *request = [self updateContainerMetadataRequestWithContainerName:containerName 
380
                                                                                        policy:policy 
381
                                                                                      metadata:metadata 
382
                                                                                        update:update];    
383
    [request addRequestHeader:@"Content-Type" value:@"application/octet-stream"];
384
	request.shouldStreamPostDataFromDisk = YES;
385
    request.postBodyFilePath = filePath;
386
	return request;
387
}
388

    
389
#pragma mark -
390
#pragma mark DELETE
391

    
392
// DELETE storageURL/container
393
+ (id)deleteContainerRequestWithContainerName:(NSString *)containerName {
394
    return [self storageRequestWithMethod:@"DELETE" containerName:containerName];
395
}
396

    
397
// DELETE storageURL/container?[until=untilTimestamp]
398
+ (id)deleteContainerRequestWithContainerName:(NSString *)containerName until:(NSDate *)untilTimestamp {
399
    NSString *queryString = nil;
400
    if (untilTimestamp)
401
        queryString = [NSString stringWithFormat:@"?until=%d", (int)[untilTimestamp timeIntervalSince1970]];
402
	return [self storageRequestWithMethod:@"DELETE" containerName:containerName queryString:queryString];    
403
}
404

    
405
#pragma mark -
406
#pragma mark NSXMLParserDelegate
407

    
408
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
409
	self.currentElement = elementName;
410
	if ([elementName isEqualToString:@"object"]) {
411
		self.currentObject = [ASIPithosObject object];
412
	} else if ([elementName isEqualToString:@"subdir"]) {
413
		[objects addObject:[ASIPithosObject subdirWithName:[attributeDict valueForKey:@"name"]]];
414
	}
415

    
416
	self.currentContent = @"";
417
}
418

    
419
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
420
	if ([elementName isEqualToString:@"name"]) {
421
        currentObject.name = currentContent;
422
	} else if ([elementName isEqualToString:@"hash"]) {
423
        currentObject.hash = currentContent;
424
	} else if ([elementName isEqualToString:@"bytes"]) {
425
        currentObject.bytes = [currentContent intValue];
426
	} else if ([elementName isEqualToString:@"content_type"]) {
427
        currentObject.contentType = currentContent;
428
	} else if ([elementName isEqualToString:@"content_encoding"]) {
429
        currentObject.contentEncoding = currentContent;
430
	} else if ([elementName isEqualToString:@"content_disposition"]) {
431
        currentObject.contentDisposition = currentContent;
432
    } else if ([elementName isEqualToString:@"last_modified"]) {
433
        currentObject.lastModified = [[self dateFormatterWithFormatId:0] dateFromString:
434
         [currentContent stringByReplacingOccurrencesOfString:@":" 
435
                                                   withString:@"" 
436
                                                      options:NSBackwardsSearch 
437
                                                        range:NSMakeRange(([currentContent length] - 3), 1)]];
438
	} else if ([elementName isEqualToString:@"x_object_version"]) {
439
        currentObject.version = currentContent;
440
    } else if ([elementName isEqualToString:@"x_object_version_timestamp"]) {
441
        currentObject.versionTimestamp = [NSDate dateWithTimeIntervalSince1970:[currentContent doubleValue]];
442
	} else if ([elementName isEqualToString:@"x_object_modified_by"]) {
443
        currentObject.modifiedBy = currentContent;
444
	} else if ([elementName isEqualToString:@"x_object_manifest"]) {
445
        currentObject.manifest = currentContent;
446
	} else if ([elementName isEqualToString:@"x_object_sharing"]) {
447
        currentObject.sharing = currentContent;
448
	} else if ([elementName isEqualToString:@"x_object_shared_by"]) {
449
        currentObject.sharedBy = currentContent;
450
	} else if ([elementName isEqualToString:@"x_object_public"]) {
451
        currentObject.publicURI = currentContent;
452
    } else if ([elementName rangeOfString:@"x_object_meta_"].location == 0) {    
453
        if (currentObject.metadata == nil)
454
            currentObject.metadata = [NSMutableDictionary dictionary];
455
        [currentObject.metadata setObject:currentContent forKey:[elementName substringFromIndex:14]];
456
	} else if ([elementName isEqualToString:@"x_object_allowed_to"]) {
457
        currentObject.allowedTo = currentContent;
458
	} else if ([elementName isEqualToString:@"object"]) {
459
		[objects addObject:currentObject];
460
        self.currentObject = nil;
461
	}
462
}
463

    
464
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
465
    self.currentContent = [currentContent stringByAppendingString:string];
466
}
467
    
468
@end