Michael Mayo

tests, container, and object support

... ... @@ -16,7 +16,7 @@
NSString *contentType;
NSDate *lastModified;
NSData *data;
NSDictionary *metadata;
NSMutableDictionary *metadata;
}
@property (nonatomic, retain) NSString *name;
... ... @@ -25,7 +25,7 @@
@property (nonatomic, retain) NSString *contentType;
@property (nonatomic, retain) NSDate *lastModified;
@property (nonatomic, retain) NSData *data;
@property (nonatomic, retain) NSDictionary *metadata;
@property (nonatomic, retain) NSMutableDictionary *metadata;
+ (id)object;
... ...
... ... @@ -12,6 +12,9 @@
@interface ASICloudFilesObjectRequest : ASICloudFilesRequest {
NSString *accountName;
NSString *containerName;
// Internally used while parsing the response
NSString *currentContent;
NSString *currentElement;
... ... @@ -20,6 +23,9 @@
}
@property (nonatomic, retain) NSString *accountName;
@property (nonatomic, retain) NSString *containerName;
@property (nonatomic, retain) NSString *currentElement;
@property (nonatomic, retain) NSString *currentContent;
@property (nonatomic, retain) ASICloudFilesObject *currentObject;
... ... @@ -31,6 +37,10 @@
- (NSUInteger)containerObjectCount;
- (NSUInteger)containerBytesUsed;
// HEAD /<api version>/<account>/<container>/<object>
// to get metadata
+ (id)objectInfoRequest:(NSString *)containerName objectPath:(NSString *)objectPath;
// GET
- (NSArray *)objects;
... ...
... ... @@ -13,6 +13,7 @@
@implementation ASICloudFilesObjectRequest
@synthesize currentElement, currentContent, currentObject;
@synthesize accountName, containerName;
+ (id)storageRequestWithMethod:(NSString *)method containerName:(NSString *)containerName {
NSString *urlString = [NSString stringWithFormat:@"%@/%@", [ASICloudFilesRequest storageURL], containerName];
... ... @@ -20,6 +21,7 @@
ASICloudFilesObjectRequest *request = [[ASICloudFilesObjectRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setRequestMethod:method];
[request addRequestHeader:@"X-Auth-Token" value:[ASICloudFilesRequest authToken]];
request.containerName = containerName;
return request;
}
... ... @@ -29,6 +31,7 @@
ASICloudFilesObjectRequest *request = [[ASICloudFilesObjectRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setRequestMethod:method];
[request addRequestHeader:@"X-Auth-Token" value:[ASICloudFilesRequest authToken]];
request.containerName = containerName;
return request;
}
... ... @@ -38,6 +41,7 @@
ASICloudFilesObjectRequest *request = [[ASICloudFilesObjectRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setRequestMethod:method];
[request addRequestHeader:@"X-Auth-Token" value:[ASICloudFilesRequest authToken]];
request.containerName = containerName;
return request;
}
... ... @@ -58,6 +62,14 @@
}
#pragma mark -
#pragma mark Object Info
+ (id)objectInfoRequest:(NSString *)containerName objectPath:(NSString *)objectPath {
ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"HEAD" containerName:containerName objectPath:objectPath];
return request;
}
#pragma mark -
#pragma mark List Requests
+ (NSString *)queryStringWithContainer:(NSString *)container limit:(NSUInteger)limit marker:(NSString *)marker prefix:(NSString *)prefix path:(NSString *)path {
... ... @@ -166,23 +178,38 @@
#pragma mark GET Object
+ (id)getObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath {
return nil;
return [ASICloudFilesObjectRequest storageRequestWithMethod:@"GET" containerName:containerName objectPath:objectPath];
}
- (ASICloudFilesObject *)object {
ASICloudFilesObject *object = [ASICloudFilesObject object];
object.name = nil; // TODO: store this cleanly somehow
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"];
// TODO: hash == ETag?
//object.etag = [[self responseHeaders] objectForKey:@"ETag"];
object.metadata = nil;
object.metadata = [[NSMutableDictionary alloc] init];
NSDictionary *headers = [self responseHeaders];
NSArray *keys = [headers allKeys];
for (int i = 0; i < [keys count]; i++) {
NSString *key = [keys objectAtIndex:i];
NSString *value = [headers objectForKey:key];
NSRange range = [key rangeOfString:@"X-Object-Meta-"];
if (range.location == 0) {
[object.metadata setObject:value forKey:[key substringFromIndex:range.length]];
}
}
object.data = [self responseData];
return nil;
return object;
}
#pragma mark -
... ... @@ -196,7 +223,7 @@
// TODO: etag?
ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath];
ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath];
[request addRequestHeader:@"Content-Type" value:contentType];
[request addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%i", objectData.length]];
... ... @@ -222,7 +249,7 @@
}
+ (id)postObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath metadata:(NSDictionary *)metadata {
ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath];
ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"POST" containerName:containerName objectPath:objectPath];
// add metadata to headers
if (metadata) {
... ... @@ -293,5 +320,13 @@
[self setCurrentContent:[[self currentContent] stringByAppendingString:string]];
}
- (void)dealloc {
[currentElement release];
[currentContent release];
[currentObject release];
[accountName release];
[containerName release];
[super dealloc];
}
@end
... ...
... ... @@ -27,6 +27,7 @@
}
+ (NSString *)storageURL;
+ (NSString *)cdnManagementURL;
+ (NSString *)authToken;
#pragma mark Rackspace Cloud Authentication
... ...
... ... @@ -22,15 +22,18 @@ static NSString *rackspaceCloudAuthURL = @"https://auth.api.rackspacecloud.com/v
@implementation ASICloudFilesRequest
+ (NSString *)authToken {
return authToken;
}
+ (NSString *)storageURL {
return storageURL;
}
+ (NSString *)authToken {
return authToken;
+ (NSString *)cdnManagementURL {
return cdnManagementURL;
}
+ (id)authenticationRequest {
ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:rackspaceCloudAuthURL]];
... ...
... ... @@ -21,7 +21,7 @@
#import "ASIInputStream.h"
// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.2-27 2010-01-07";
NSString *ASIHTTPRequestVersion = @"v1.2-28 2010-01-08";
// We use our own custom run loop mode as CoreAnimation seems to want to hijack our threads otherwise
static CFStringRef ASIHTTPRequestRunMode = CFSTR("ASIHTTPRequest");
... ...
... ... @@ -6,13 +6,40 @@
// Copyright 2010 __MyCompanyName__. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "ASITestCase.h"
@class ASINetworkQueue;
@interface ASICloudFilesRequestTests : NSObject {
@interface ASICloudFilesRequestTests : ASITestCase {
ASINetworkQueue *networkQueue;
float progress;
}
@property (retain,nonatomic) ASINetworkQueue *networkQueue;
// Convenience Constructors
- (void)testSubclasses;
// ASICloudFilesRequest
- (void)testAuthentication;
- (void)testDateParser;
// ASICloudFilesContainerRequest
- (void)testAccountInfo;
- (void)testContainerList; // TODO: with marker and limit permutations as well
- (void)testContainerCreate;
- (void)testContainerDelete;
// ASICloudFilesObjectRequest
- (void)testContainerInfo;
- (void)testObjectInfo;
- (void)testObjectList; // TODO: all permutations
- (void)testGetObject;
- (void)testPutObject; // TODO: all permutations?
- (void)testPostObject; // TODO: all permutations?
- (void)testDeleteObject;
// ASICloudFilesCDNRequest
// ???
@end
... ...
This diff is collapsed. Click to expand it.
... ... @@ -9,12 +9,6 @@
#import "iPhoneSampleAppDelegate.h"
#import "ASIHTTPRequest.h"
#import "Reachability.h"
#import "ASICloudFilesRequest.h"
#import "ASICloudFilesContainerRequest.h"
#import "ASICloudFilesObjectRequest.h"
#import "ASICloudFilesCDNRequest.h"
#import "ASICloudFilesContainer.h"
#import "ASICloudFilesObject.h"
@implementation iPhoneSampleAppDelegate
... ... @@ -29,129 +23,7 @@
[super dealloc];
}
// TODO: remove
-(NSDate *)dateFromString:(NSString *)dateString {
NSDateFormatter *format = [[NSDateFormatter alloc] init];
// example: 2009-11-04T19:46:20.192723
//[format setDateFormat:@"EEE, d MMM yyyy H:mm:ss zzz"];
//[format setDateFormat:@"yyyy-MM-ddTH:mm:ss"];
[format setDateFormat:@"yyyy-MM-dd'T'H:mm:ss"];
NSDate *date = [format dateFromString:dateString];
[format release];
return date;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(@"DATE TESTS!!!");
NSDate *date = [self dateFromString:@"2009-11-04T19:46:20.192723"];
NSLog(@"date: %@", [date description]);
NSLog(@"time to test Cloud Files!");
[ASICloudFilesRequest setUsername:@"greenisus"];
[ASICloudFilesRequest setApiKey:@"1c331a7a4a6eb58ca6072afe81e812d0"];
[ASICloudFilesRequest authenticate];
NSLog(@"Storage URL: %@", [ASICloudFilesRequest storageURL]);
NSArray *containers = nil;
containers; // to suppress warning when test are commented out
/*
NSLog(@"account info:");
ASICloudFilesContainerRequest *accountInfoRequest = [ASICloudFilesContainerRequest accountInfoRequest];
[accountInfoRequest start];
// NSLog(@"Response status code: %i", [accountInfoRequest responseStatusCode]);
// NSLog(@"Response status message: %@", [accountInfoRequest responseStatusMessage]);
NSLog(@"Container count: %i", [accountInfoRequest containerCount]);
NSLog(@"Bytes used: %i", [accountInfoRequest bytesUsed]);
// NSLog(@"All headers:");
// NSDictionary *headers = [accountInfoRequest responseHeaders];
// NSArray *keys = [headers allKeys];
// for (int i = 0; i < [keys count]; i++) {
// NSString *key = [keys objectAtIndex:i];
// NSLog(@"%@: %@", key, [headers objectForKey:key]);
// }
ASICloudFilesContainerRequest *containerListRequest = [ASICloudFilesContainerRequest listRequest];
[containerListRequest start];
containers = [containerListRequest containers];
NSLog(@"Containers list count: %i", [containers count]);
for (int i = 0; i < [containers count]; i++) {
ASICloudFilesContainer *container = [containers objectAtIndex:i];
NSLog(@"%@ - %i objects, %i bytes", container.name, container.count, container.bytes);
}
ASICloudFilesContainerRequest *limitContainerListRequest = [ASICloudFilesContainerRequest listRequestWithLimit:2];
[limitContainerListRequest start];
containers = [limitContainerListRequest containers];
NSLog(@"Limit 2 Containers list count: %i", [containers count]);
for (int i = 0; i < [containers count]; i++) {
ASICloudFilesContainer *container = [containers objectAtIndex:i];
NSLog(@"%@ - %i objects, %i bytes", container.name, container.count, container.bytes);
}
ASICloudFilesContainerRequest *markerContainerListRequest = [ASICloudFilesContainerRequest listRequestWithMarker:@"personal"];
[markerContainerListRequest start];
containers = [markerContainerListRequest containers];
NSLog(@"Marker personal Containers list count: %i", [containers count]);
for (int i = 0; i < [containers count]; i++) {
ASICloudFilesContainer *container = [containers objectAtIndex:i];
NSLog(@"%@ - %i objects, %i bytes", container.name, container.count, container.bytes);
}
ASICloudFilesContainerRequest *limitMarkerContainerListRequest = [ASICloudFilesContainerRequest listRequestWithLimit:3 marker:@"cf_service"];
[limitMarkerContainerListRequest start];
containers = [limitMarkerContainerListRequest containers];
NSLog(@"Limit 3 Marker cf_service Containers list count: %i", [containers count]);
for (int i = 0; i < [containers count]; i++) {
ASICloudFilesContainer *container = [containers objectAtIndex:i];
NSLog(@"%@ - %i objects, %i bytes", container.name, container.count, container.bytes);
}
ASICloudFilesContainerRequest *createContainerRequest = [ASICloudFilesContainerRequest createContainerRequest:@"ASICloudFiles"];
[createContainerRequest start];
NSLog(@"Create response status code: %i", [createContainerRequest responseStatusCode]);
NSLog(@"Create response status message: %@", [createContainerRequest responseStatusMessage]);
ASICloudFilesContainerRequest *deleteContainerRequest = [ASICloudFilesContainerRequest deleteContainerRequest:@"ASICloudFiles"];
[deleteContainerRequest start];
NSLog(@"Delete response status code: %i", [deleteContainerRequest responseStatusCode]);
NSLog(@"Delete response status message: %@", [deleteContainerRequest responseStatusMessage]);
*/
// OBJECT LIST TEST
/*
ASICloudFilesObjectRequest *objectListRequest = [ASICloudFilesObjectRequest listRequestWithContainer:@"cf_service"];
[objectListRequest start];
containers = [objectListRequest objects];
NSLog(@"cf_service object list count: %i", [containers count]);
for (int i = 0; i < [containers count]; i++) {
ASICloudFilesObject *object = [containers objectAtIndex:i];
NSLog(@"%@ - %@ - %i bytes, %@, %@", object.name, object.hash, object.bytes, object.contentType, [object.lastModified description]);
}
*/
// Add the tab bar controller's current view as a subview of the window
[window addSubview:[tabBarController view]];
[[tabBarController view] setFrame:CGRectMake(0,47,320,433)];
... ...