New file |
| | |
| | | // |
| | | // ASICloudFilesObjectRequest.m |
| | | // |
| | | // Created by Michael Mayo on 1/6/10. |
| | | // |
| | | |
| | | #import "ASICloudFilesObjectRequest.h" |
| | | #import "ASICloudFilesObject.h" |
| | | |
| | | |
| | | @implementation ASICloudFilesObjectRequest |
| | | |
| | | @synthesize currentElement, currentContent, currentObject; |
| | | @synthesize accountName, containerName; |
| | | |
| | | #pragma mark - |
| | | #pragma mark Constructors |
| | | |
| | | + (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName { |
| | | NSString *urlString = [NSString stringWithFormat:@"%@/%@", [ASICloudFilesRequest storageURL], containerName]; |
| | | ASICloudFilesObjectRequest *request = [[[ASICloudFilesObjectRequest alloc] initWithURL:[NSURL URLWithString:urlString]] autorelease]; |
| | | [request setRequestMethod:method]; |
| | | [request addRequestHeader:@"X-Auth-Token" value:[ASICloudFilesRequest authToken]]; |
| | | request.containerName = containerName; |
| | | return request; |
| | | } |
| | | |
| | | + (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName queryString:(NSString *)queryString { |
| | | NSString *urlString = [NSString stringWithFormat:@"%@/%@%@", [ASICloudFilesRequest storageURL], containerName, queryString]; |
| | | ASICloudFilesObjectRequest *request = [[[ASICloudFilesObjectRequest alloc] initWithURL:[NSURL URLWithString:urlString]] autorelease]; |
| | | [request setRequestMethod:method]; |
| | | [request addRequestHeader:@"X-Auth-Token" value:[ASICloudFilesRequest authToken]]; |
| | | request.containerName = containerName; |
| | | return request; |
| | | } |
| | | |
| | | + (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName objectPath:(NSString *)objectPath { |
| | | NSString *urlString = [NSString stringWithFormat:@"%@/%@/%@", [ASICloudFilesRequest storageURL], containerName, objectPath]; |
| | | ASICloudFilesObjectRequest *request = [[[ASICloudFilesObjectRequest alloc] initWithURL:[NSURL URLWithString:urlString]] autorelease]; |
| | | [request setRequestMethod:method]; |
| | | [request addRequestHeader:@"X-Auth-Token" value:[ASICloudFilesRequest authToken]]; |
| | | request.containerName = containerName; |
| | | return request; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark HEAD - Container Info |
| | | |
| | | + (id)containerInfoRequest:(NSString *)containerName { |
| | | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"HEAD" containerName:containerName]; |
| | | return request; |
| | | } |
| | | |
| | | - (NSUInteger)containerObjectCount { |
| | | return [[[self responseHeaders] objectForKey:@"X-Container-Object-Count"] intValue]; |
| | | } |
| | | |
| | | - (NSUInteger)containerBytesUsed { |
| | | return [[[self responseHeaders] objectForKey:@"X-Container-Bytes-Used"] intValue]; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark HEAD - Object Info |
| | | |
| | | + (id)objectInfoRequest:(NSString *)containerName objectPath:(NSString *)objectPath { |
| | | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"HEAD" containerName:containerName objectPath:objectPath]; |
| | | return request; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark GET - List Objects |
| | | |
| | | + (NSString *)queryStringWithContainer:(NSString *)container limit:(NSUInteger)limit marker:(NSString *)marker prefix:(NSString *)prefix path:(NSString *)path { |
| | | NSString *queryString = @"?format=xml"; |
| | | |
| | | if (limit && limit > 0) { |
| | | queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&limit=%i", limit]]; |
| | | } |
| | | if (marker) { |
| | | queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&marker=%@", [marker stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; |
| | | } |
| | | if (path) { |
| | | queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@"&path=%@", [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; |
| | | } |
| | | |
| | | return queryString; |
| | | } |
| | | |
| | | + (id)listRequestWithContainer:(NSString *)containerName limit:(NSUInteger)limit marker:(NSString *)marker prefix:(NSString *)prefix path:(NSString *)path { |
| | | NSString *queryString = [ASICloudFilesObjectRequest queryStringWithContainer:containerName limit:limit marker:marker prefix:prefix path:path]; |
| | | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"GET" containerName:containerName queryString:queryString]; |
| | | return request; |
| | | } |
| | | |
| | | + (id)listRequestWithContainer:(NSString *)containerName { |
| | | return [ASICloudFilesObjectRequest listRequestWithContainer:containerName limit:0 marker:nil prefix:nil path:nil]; |
| | | } |
| | | |
| | | - (NSArray *)objects { |
| | | if (objects) { |
| | | return objects; |
| | | } |
| | | objects = [[[NSMutableArray alloc] init] autorelease]; |
| | | |
| | | NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease]; |
| | | [parser setDelegate:self]; |
| | | [parser setShouldProcessNamespaces:NO]; |
| | | [parser setShouldReportNamespacePrefixes:NO]; |
| | | [parser setShouldResolveExternalEntities:NO]; |
| | | [parser parse]; |
| | | return objects; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark GET - Retrieve Object |
| | | |
| | | + (id)getObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath { |
| | | return [ASICloudFilesObjectRequest storageRequestWithMethod:@"GET" containerName:containerName objectPath:objectPath]; |
| | | } |
| | | |
| | | - (ASICloudFilesObject *)object { |
| | | ASICloudFilesObject *object = [ASICloudFilesObject object]; |
| | | |
| | | NSString *path = [self url].path; |
| | | NSRange range = [path rangeOfString:self.containerName]; |
| | | path = [path substringFromIndex:range.location + range.length + 1]; |
| | | |
| | | object.name = path; |
| | | object.hash = [[self responseHeaders] objectForKey:@"ETag"]; |
| | | object.bytes = [[[self responseHeaders] objectForKey:@"Content-Length"] intValue]; |
| | | object.contentType = [[self responseHeaders] objectForKey:@"Content-Type"]; |
| | | object.lastModified = [[self responseHeaders] objectForKey:@"Last-Modified"]; |
| | | object.metadata = [NSMutableDictionary dictionary]; |
| | | |
| | | for (NSString *key in [[self responseHeaders] keyEnumerator]) { |
| | | NSRange metaRange = [key rangeOfString:@"X-Object-Meta-"]; |
| | | if (metaRange.location == 0) { |
| | | [object.metadata setObject:[[self responseHeaders] objectForKey:key] forKey:[key substringFromIndex:metaRange.length]]; |
| | | } |
| | | } |
| | | |
| | | object.data = [self responseData]; |
| | | |
| | | return object; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark PUT - Upload Object |
| | | |
| | | + (id)putObjectRequestWithContainer:(NSString *)containerName object:(ASICloudFilesObject *)object { |
| | | return [self putObjectRequestWithContainer:containerName objectPath:object.name contentType:object.contentType objectData:object.data metadata:object.metadata etag:nil]; |
| | | } |
| | | |
| | | + (id)putObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath contentType:(NSString *)contentType objectData:(NSData *)objectData metadata:(NSDictionary *)metadata etag:(NSString *)etag { |
| | | |
| | | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath]; |
| | | [request addRequestHeader:@"Content-Type" value:contentType]; |
| | | |
| | | // add metadata to headers |
| | | if (metadata) { |
| | | for (NSString *key in [metadata keyEnumerator]) { |
| | | [request addRequestHeader:[NSString stringWithFormat:@"X-Object-Meta-%@", key] value:[metadata objectForKey:key]]; |
| | | } |
| | | } |
| | | |
| | | [request appendPostData:objectData]; |
| | | return request; |
| | | } |
| | | |
| | | + (id)putObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath contentType:(NSString *)contentType file:(NSString *)filePath metadata:(NSDictionary *)metadata etag:(NSString *)etag |
| | | { |
| | | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath]; |
| | | [request addRequestHeader:@"Content-Type" value:contentType]; |
| | | |
| | | // add metadata to headers |
| | | if (metadata) { |
| | | for (NSString *key in [metadata keyEnumerator]) { |
| | | [request addRequestHeader:[NSString stringWithFormat:@"X-Object-Meta-%@", key] value:[metadata objectForKey:key]]; |
| | | } |
| | | } |
| | | |
| | | [request setShouldStreamPostDataFromDisk:YES]; |
| | | [request setPostBodyFilePath:filePath]; |
| | | return request; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark POST - Set Object Metadata |
| | | |
| | | + (id)postObjectRequestWithContainer:(NSString *)containerName object:(ASICloudFilesObject *)object { |
| | | return [self postObjectRequestWithContainer:containerName objectPath:object.name metadata:object.metadata]; |
| | | } |
| | | |
| | | + (id)postObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath metadata:(NSDictionary *)metadata { |
| | | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"POST" containerName:containerName objectPath:objectPath]; |
| | | |
| | | // add metadata to headers |
| | | if (metadata) { |
| | | for (NSString *key in [metadata keyEnumerator]) { |
| | | [request addRequestHeader:[NSString stringWithFormat:@"X-Object-Meta-%@", key] value:[metadata objectForKey:key]]; |
| | | } |
| | | } |
| | | |
| | | return request; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark DELETE - Delete Object |
| | | |
| | | + (id)deleteObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath { |
| | | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"DELETE" containerName:containerName objectPath:objectPath]; |
| | | return request; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark XML Parser Delegate |
| | | |
| | | - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { |
| | | [self setCurrentElement:elementName]; |
| | | |
| | | if ([elementName isEqualToString:@"object"]) { |
| | | [self setCurrentObject:[ASICloudFilesObject object]]; |
| | | } |
| | | [self setCurrentContent:@""]; |
| | | } |
| | | |
| | | - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { |
| | | if ([elementName isEqualToString:@"name"]) { |
| | | [self currentObject].name = [self currentContent]; |
| | | } else if ([elementName isEqualToString:@"hash"]) { |
| | | [self currentObject].hash = [self currentContent]; |
| | | } else if ([elementName isEqualToString:@"bytes"]) { |
| | | [self currentObject].bytes = [[self currentContent] intValue]; |
| | | } else if ([elementName isEqualToString:@"content_type"]) { |
| | | [self currentObject].contentType = [self currentContent]; |
| | | } else if ([elementName isEqualToString:@"last_modified"]) { |
| | | [self currentObject].lastModified = [self dateFromString:[self currentContent]]; |
| | | } else if ([elementName isEqualToString:@"object"]) { |
| | | // we're done with this object. time to move on to the next |
| | | [objects addObject:currentObject]; |
| | | [self setCurrentObject:nil]; |
| | | } |
| | | } |
| | | |
| | | - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { |
| | | [self setCurrentContent:[[self currentContent] stringByAppendingString:string]]; |
| | | } |
| | | |
| | | #pragma mark - |
| | | #pragma mark Memory Management |
| | | |
| | | - (void)dealloc { |
| | | [currentElement release]; |
| | | [currentContent release]; |
| | | [currentObject release]; |
| | | [accountName release]; |
| | | [containerName release]; |
| | | [super dealloc]; |
| | | } |
| | | |
| | | @end |