Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Classes / Pithos / ASIPithosAccountRequest.m @ 2f6bc433

History | View | Annotate | Download (13.2 kB)

1
//  ASIPithosAccountRequest.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 "ASIPithosAccountRequest.h"
38
#import "ASIPithos.h"
39
#import "ASIPithosAccount.h"
40
#import "ASIPithosContainer.h"
41

    
42
@implementation ASIPithosAccountRequest
43
@synthesize currentContainer, currentDictionary, currentKey;
44

    
45
#pragma mark -
46
#pragma mark Constructors
47

    
48
+ (id)storageRequestWithMethod:(NSString *)method pithos:(ASIPithos *)pithos queryString:(NSString *)queryString {
49
    NSString *urlString = pithos.storageURL;
50
    if (queryString)
51
        urlString = [urlString stringByAppendingString:queryString];
52

    
53
	ASIPithosAccountRequest *request = [self requestWithURL:[NSURL URLWithString:urlString]];
54
	[request setRequestMethod:method];
55
	[request addRequestHeader:@"X-Auth-Token" value:pithos.authToken];
56
    request.validatesSecureCertificate = !pithos.ignoreSSLErrors;
57
    request.retryBaseURLString = pithos.storageURLPrefix;
58
    request.retryType = ASIPithosRequestTypeStorage;
59
	return request;
60
}
61

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

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

    
69
- (void)dealloc {
70
    [currentKey release];
71
	[currentContainer release];
72
    [containers release];
73
    [metadata release];
74
    [policy release];
75
    [groups release];
76
	[super dealloc];
77
}
78

    
79
#pragma mark -
80
#pragma mark HEAD
81

    
82
// HEAD storageURL
83
+ (id)accountMetadataRequestWithPithos:(ASIPithos *)pithos {
84
	return [self storageRequestWithMethod:@"HEAD" pithos:pithos];
85
}
86

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

    
95
// HEAD storageURL?[until=untilTimestamp] [If-Modified-Since]
96
+ (id)accountMetadataRequestWithPithos:(ASIPithos *)pithos until:(NSDate *)untilTimestamp ifModifiedSince:(NSDate *)sinceTimestamp {
97
    ASIPithosAccountRequest *request = [self accountMetadataRequestWithPithos:pithos until:untilTimestamp];
98
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
99
    return request;
100
}
101

    
102
// HEAD storageURL?[until=untilTimestamp] [If-Unmodified-Since]
103
+ (id)accountMetadataRequestWithPithos:(ASIPithos *)pithos until:(NSDate *)untilTimestamp ifUnmodifiedSince:(NSDate *)sinceTimestamp {
104
    ASIPithosAccountRequest *request = [self accountMetadataRequestWithPithos:pithos until:untilTimestamp];
105
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
106
    return request;
107
}
108

    
109
- (NSUInteger)containerCount {
110
	return [[[self responseHeaders] objectForKey:@"X-Account-Container-Count"] integerValue];
111
}
112

    
113
- (NSUInteger)bytesUsed {
114
	return [[[self responseHeaders] objectForKey:@"X-Account-Bytes-Used"] integerValue];
115
}
116

    
117
- (NSDate *)untilTimestamp {
118
    NSString *untilTimestampString = [[self responseHeaders] objectForKey:@"X-Account-Until-Timestamp"];
119
    if (untilTimestampString)
120
        return [[self dateFormatterWithFormatId:1] dateFromString:untilTimestampString];
121
    return nil;
122
}
123

    
124
- (NSDictionary *)groups {
125
    if (groups == nil) {
126
        groups = [NSMutableDictionary dictionary];
127
        NSMutableDictionary *groupsHeaders = [self getHeadersDictionaryForPrefix:@"X-Account-Group-"];
128
        for (NSString *groupName in groupsHeaders) {
129
            [groups setObject:[[groupsHeaders objectForKey:groupName] componentsSeparatedByString:@","]
130
                       forKey:groupName];
131
        }
132
        [groups retain];
133
    }
134
    return groups;
135
}
136

    
137
- (NSDictionary *)policy {
138
    if (policy == nil) {
139
        policy = [self getHeadersDictionaryForPrefix:@"X-Account-Policy-"];
140
        [policy retain];
141
    }
142
    return policy;
143
}
144

    
145
- (NSDictionary *)metadata {
146
    if (metadata == nil) {
147
        metadata = [self getHeadersDictionaryForPrefix:@"X-Account-Meta-"];
148
        [metadata retain];
149
    }
150
    return metadata;
151
}
152

    
153
- (NSDate *)lastModified {
154
    NSString *lastModifiedString = [[self responseHeaders] objectForKey:@"Last-Modified"];
155
    if (lastModifiedString)
156
        return [[self dateFormatterWithFormatId:1] dateFromString:lastModifiedString];
157
    return nil;
158
}
159

    
160
- (ASIPithosAccount *)account {
161
    ASIPithosAccount *account = [ASIPithosAccount account];
162
    account.containerCount = [self containerCount];
163
    account.bytesUsed = [self bytesUsed];
164
    account.untilTimestamp = [self untilTimestamp];
165
    account.groups = (NSMutableDictionary *)[self groups];
166
    account.policy = (NSMutableDictionary *)[self policy];
167
    account.metadata = (NSMutableDictionary *)[self metadata];
168
    account.lastModified = [self lastModified];
169
    return account;
170
}
171

    
172

    
173
#pragma mark -
174
#pragma mark GET
175

    
176
// GET storageURL
177
+ (id)listContainersRequestWithPithos:(ASIPithos *)pithos {
178
	return [self storageRequestWithMethod:@"GET" pithos:pithos queryString:@"?format=xml"];
179
}
180

    
181
// GET storageURL?[limit=limit]&[marker=marker]&[shared=]&[until=untilTimestamp]
182
+ (id)listContainersRequestWithPithos:(ASIPithos *)pithos 
183
                                limit:(NSUInteger)limit 
184
                               marker:(NSString *)marker 
185
                               shared:(BOOL)shared 
186
                                until:(NSDate *)untilTimestamp {
187
	NSString *queryString = @"?format=xml";
188
	if (limit && (limit > 0))
189
		queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&limit=%lu", limit]];
190
	if (marker)
191
		queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&marker=%@", [self encodeToPercentEscape:marker]]];
192
	if (shared)
193
		queryString = [queryString stringByAppendingString:@"&shared="];    
194
    if (untilTimestamp)
195
        queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&until=%d", (int)[untilTimestamp timeIntervalSince1970]]];
196
	
197
	return [self storageRequestWithMethod:@"GET" pithos:pithos queryString:queryString];
198
}
199

    
200
// GET storageURL?[limit=limit]&[marker=marker]&[shared=]&[until=untilTimestamp] [If-Modified-Since]
201
+ (id)listContainersRequestWithPithos:(ASIPithos *)pithos 
202
                                limit:(NSUInteger)limit 
203
                              marker:(NSString *)marker 
204
                              shared:(BOOL)shared 
205
                               until:(NSDate *)untilTimestamp 
206
                     ifModifiedSince:(NSDate *)sinceTimestamp {
207
    ASIPithosAccountRequest *request = [self listContainersRequestWithPithos:pithos limit:limit marker:marker shared:shared until:untilTimestamp];
208
    [request addRequestIfModifiedSinceHeader:sinceTimestamp];
209
    return request;
210
}
211

    
212
// GET storageURL?[limit=limit]&[marker=marker]&[shared=]&[until=untilTimestamp] [If-Unmodified-Since]
213
+ (id)listContainersRequestWithPithos:(ASIPithos *)pithos 
214
                                limit:(NSUInteger)limit 
215
                              marker:(NSString *)marker 
216
                              shared:(BOOL)shared 
217
                               until:(NSDate *)untilTimestamp 
218
                     ifUnmodifiedSince:(NSDate *)sinceTimestamp {
219
    ASIPithosAccountRequest *request = [self listContainersRequestWithPithos:pithos limit:limit marker:marker shared:shared until:untilTimestamp];
220
    [request addRequestIfUnmodifiedSinceHeader:sinceTimestamp];
221
    return request;
222
}
223

    
224

    
225
- (NSArray *)containers {
226
    if (containers == nil) {
227
        containers = [[NSMutableArray alloc] init];
228
        
229
        NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease];
230
        [parser setDelegate:self];
231
        [parser setShouldProcessNamespaces:NO];
232
        [parser setShouldReportNamespacePrefixes:NO];
233
        [parser setShouldResolveExternalEntities:NO];
234
        [parser parse];
235
    }    
236
	return containers;
237
}
238

    
239
#pragma mark -
240
#pragma mark POST
241

    
242

    
243
// POST storageURL
244
+ (id)updateAccountMetadataRequestWithPithos:(ASIPithos *)pithos {
245
    return [self storageRequestWithMethod:@"POST" pithos:pithos];
246
}
247

    
248
// POST storageURL?[update=] [X-Account-Group-*] [X-Account-Meta-*]
249
+ (id)updateAccountMetadataRequestWithPithos:(ASIPithos *)pithos 
250
                                      groups:(NSDictionary *)groups 
251
                                    metadata:(NSDictionary *)metadata 
252
                                      update:(BOOL)update {
253
    NSString *queryString = nil;
254
    if (update)
255
        queryString = @"?update=";
256
    ASIPithosAccountRequest *request = [self storageRequestWithMethod:@"POST" pithos:pithos queryString:queryString];
257
	
258
    if (groups) {
259
        for (NSString *key in groups) {
260
            [request addRequestHeader:[self encodeToPercentEscape:[NSString stringWithFormat:@"X-Account-Group-%@", key]] 
261
                                value:[self encodeToPercentEscape:[[groups objectForKey:key] componentsJoinedByString:@","]]];
262
        }
263
    }
264
    
265
    if (metadata) {
266
        for (NSString *key in metadata) {
267
            [request addRequestHeader:[self encodeToPercentEscape:[NSString stringWithFormat:@"X-Account-Meta-%@", key]] 
268
                                value:[self encodeToPercentEscape:[metadata objectForKey:key]]];
269
        }
270
    }
271
    
272
	return request;
273
}
274

    
275
#pragma mark -
276
#pragma mark NSXMLParserDelegate
277

    
278
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
279
    self.currentElement = elementName;
280
	if ([elementName isEqualToString:@"container"]) {
281
		self.currentContainer = [ASIPithosContainer container];
282
	} else if ([elementName isEqualToString:@"x_container_policy"]) {
283
        if (currentContainer.policy == nil)
284
            currentContainer.policy = [NSMutableDictionary dictionary];
285
        self.currentDictionary = currentContainer.policy;
286
    }
287
	self.currentContent = @"";
288
}
289

    
290
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
291
	if ([elementName isEqualToString:@"name"]) {
292
        currentContainer.name = currentContent;
293
	} else if ([elementName isEqualToString:@"count"]) {
294
        currentContainer.count = [currentContent integerValue];
295
	} else if ([elementName isEqualToString:@"bytes"]) {
296
        currentContainer.bytes = [currentContent integerValue];
297
    } else if ([elementName isEqualToString:@"last_modified"]) {
298
        currentContainer.lastModified = [[self dateFormatterWithFormatId:0] dateFromString:
299
                                         [currentContent stringByReplacingOccurrencesOfString:@":" 
300
                                                                                   withString:@"" 
301
                                                                                      options:NSBackwardsSearch 
302
                                                                                        range:NSMakeRange(([currentContent length] - 3), 1)]];
303
    } else if ([elementName isEqualToString:@"x_container_until_timestamp"]) {
304
        currentContainer.untilTimestamp = [NSDate dateWithTimeIntervalSince1970:[currentContent doubleValue]];
305
    } else if ([elementName isEqualToString:@"key"]) {
306
        self.currentKey = currentContent;
307
    } else if ([elementName isEqualToString:@"value"]) {
308
        [currentDictionary setObject:currentContent forKey:currentKey];
309
        self.currentKey = nil;
310
    } else if ([elementName isEqualToString:@"x_container_policy"]) {
311
        self.currentDictionary = nil;
312
	} else if ([elementName isEqualToString:@"container"]) {
313
		[containers addObject:currentContainer];
314
        self.currentContainer = nil;
315
	}
316
}
317

    
318
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
319
    self.currentContent = [currentContent stringByAppendingString:string];
320
}
321
    
322
@end