Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Classes / Pithos / ASIPithosAccountRequest.m @ 8fb25a1b

History | View | Annotate | Download (13.1 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 copy] autorelease];
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
	return request;
58
}
59

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

    
64
#pragma mark -
65
#pragma mark Memory Management
66

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

    
77
#pragma mark -
78
#pragma mark HEAD
79

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

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

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

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

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

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

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

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

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

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

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

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

    
170

    
171
#pragma mark -
172
#pragma mark GET
173

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

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

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

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

    
222

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

    
237
#pragma mark -
238
#pragma mark POST
239

    
240

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

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

    
273
#pragma mark -
274
#pragma mark NSXMLParserDelegate
275

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

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

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