Skip to content

Commit

Permalink
More work on S3 refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
pokeb committed Mar 16, 2010
1 parent 198761b commit f3b6bc4
Show file tree
Hide file tree
Showing 14 changed files with 261 additions and 77 deletions.
2 changes: 1 addition & 1 deletion Classes/ASIHTTPRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#import "ASIInputStream.h"

// Automatically set on build
NSString *ASIHTTPRequestVersion = @"v1.6-6 2010-03-16";
NSString *ASIHTTPRequestVersion = @"v1.6-7 2010-03-16";

NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain";

Expand Down
34 changes: 34 additions & 0 deletions Classes/ASIS3Bucket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// ASIS3Bucket.h
// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
//
// Created by Ben Copsey on 16/03/2010.
// Copyright 2010 All-Seeing Interactive. All rights reserved.
//
// Instances of this class represent buckets stored on S3
// ASIS3ServiceRequests return an array of ASIS3Buckets when you perform a service GET query
// You'll probably never need to create instances of ASIS3Bucket yourself

#import <Foundation/Foundation.h>


@interface ASIS3Bucket : NSObject {

// The name of this bucket (will be unique throughout S3)
NSString *name;

// The date this bucket was created
NSDate *creationDate;

// Information about the owner of this bucket
NSString *ownerID;
NSString *ownerName;
}

+ (id)bucketWithOwnerID:(NSString *)ownerID ownerName:(NSString *)ownerName;

@property (retain) NSString *name;
@property (retain) NSDate *creationDate;
@property (retain) NSString *ownerID;
@property (retain) NSString *ownerName;
@end
32 changes: 32 additions & 0 deletions Classes/ASIS3Bucket.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// ASIS3Bucket.m
// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest
//
// Created by Ben Copsey on 16/03/2010.
// Copyright 2010 All-Seeing Interactive. All rights reserved.
//

#import "ASIS3Bucket.h"


@implementation ASIS3Bucket

+ (id)bucketWithOwnerID:(NSString *)ownerID ownerName:(NSString *)ownerName
{
ASIS3Bucket *bucket = [[[self alloc] init] autorelease];
[bucket setOwnerID:ownerID];
[bucket setOwnerName:ownerName];
return bucket;
}

- (NSString *)description
{
return [NSString stringWithFormat:@"Name: %@ creationDate: %@ ownerID: %@ ownerName: %@",[self name],[self creationDate],[self ownerID],[self ownerName]];
}


@synthesize name;
@synthesize creationDate;
@synthesize ownerID;
@synthesize ownerName;
@end
8 changes: 4 additions & 4 deletions Classes/ASIS3BucketRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@
@class ASIS3BucketObject;

@interface ASIS3BucketRequest : ASIS3Request {

// Name of the bucket to talk to
NSString *bucket;

// A parameter passed to S3 in the query string to tell it to return specialised information
// Consult the S3 REST API documentation for more info
NSString *subResource;

// Options for filtering GET requests
Expand Down Expand Up @@ -56,10 +60,6 @@
//Builds a query string out of the list parameters we supplied
- (void)createQueryString;

// Returns a date formatter than can be used to parse a date from S3
+ (NSDateFormatter *)dateFormatter;


@property (retain) NSString *bucket;
@property (retain) NSString *subResource;
@property (retain) NSString *prefix;
Expand Down
19 changes: 1 addition & 18 deletions Classes/ASIS3BucketRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#import "ASIS3BucketRequest.h"
#import "ASIS3BucketObject.h"

static NSDateFormatter *dateFormatter = nil;


// Private stuff
@interface ASIS3BucketRequest ()
Expand All @@ -22,18 +20,6 @@ @interface ASIS3BucketRequest ()

@implementation ASIS3BucketRequest

+ (NSDateFormatter *)dateFormatter
{
if (!dateFormatter) {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'.000Z'"];
}
return dateFormatter;
}


+ (id)requestWithBucket:(NSString *)bucket
{
ASIS3ObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com",bucket]]] autorelease];
Expand Down Expand Up @@ -87,9 +73,6 @@ - (NSString *)canonicalizedResource
return [NSString stringWithFormat:@"/%@/",[self bucket]];
}




- (void)createQueryString
{
NSMutableArray *queryParts = [[[NSMutableArray alloc] init] autorelease];
Expand Down Expand Up @@ -149,7 +132,7 @@ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName names
} else if ([elementName isEqualToString:@"Key"]) {
[[self currentObject] setKey:[self currentContent]];
} else if ([elementName isEqualToString:@"LastModified"]) {
[[self currentObject] setLastModified:[[ASIS3BucketRequest dateFormatter] dateFromString:[self currentContent]]];
[[self currentObject] setLastModified:[[ASIS3Request dateFormatter] dateFromString:[self currentContent]]];
} else if ([elementName isEqualToString:@"ETag"]) {
[[self currentObject] setETag:[self currentContent]];
} else if ([elementName isEqualToString:@"Size"]) {
Expand Down
2 changes: 1 addition & 1 deletion Classes/ASIS3ObjectRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Ben Copsey on 16/03/2010.
// Copyright 2010 All-Seeing Interactive. All rights reserved.
//
// Use this class to fetch, upload, copy and delete objects on Amazon S3
// Use an ASIS3ObjectRequest to fetch, upload, copy and delete objects on Amazon S3

#import <Foundation/Foundation.h>
#import "ASIS3Request.h"
Expand Down
7 changes: 1 addition & 6 deletions Classes/ASIS3ObjectRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ - (void)dealloc
[mimeType release];
[sourceKey release];
[sourceBucket release];
[accessPolicy release];
[super dealloc];
}

Expand All @@ -120,10 +119,7 @@ - (NSString *)canonicalizedResource

- (NSMutableDictionary *)S3Headers
{
NSMutableDictionary *headers = [NSMutableDictionary dictionary];
if ([self accessPolicy]) {
[headers setObject:[self accessPolicy] forKey:@"x-amz-acl"];
}
NSMutableDictionary *headers = [super S3Headers];
if ([self sourceKey]) {
NSString *path = [ASIS3Request stringByURLEncodingForS3Path:[self sourceKey]];
[headers setObject:[[self sourceBucket] stringByAppendingString:path] forKey:@"x-amz-copy-source"];
Expand All @@ -146,5 +142,4 @@ - (NSString *)stringToSignForHeaders:(NSString *)canonicalizedAmzHeaders resourc
@synthesize sourceBucket;
@synthesize sourceKey;
@synthesize mimeType;
@synthesize accessPolicy;
@end
16 changes: 15 additions & 1 deletion Classes/ASIS3ServiceRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,24 @@
#import <Foundation/Foundation.h>
#import "ASIS3Request.h"

@interface ASIS3ServiceRequest : ASIS3Request {
@class ASIS3Bucket;

@interface ASIS3ServiceRequest : ASIS3Request {

// Internally used while parsing the response
NSString *currentContent;
NSString *currentElement;
ASIS3Bucket *currentBucket;
NSMutableArray *buckets;
NSString *ownerName;
NSString *ownerID;
}

// Perform a GET request on the S3 service
// This will fetch a list of the buckets attached to the S3 account
+ (id)serviceRequest;

// Parse the XML response from S3, and return an array of ASIS3Bucket objects
- (NSArray *)allBuckets;

@end
72 changes: 72 additions & 0 deletions Classes/ASIS3ServiceRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@
//

#import "ASIS3ServiceRequest.h"
#import "ASIS3Bucket.h"

// Private stuff
@interface ASIS3ServiceRequest ()
@property (retain, nonatomic) NSMutableArray *buckets;
@property (retain, nonatomic) NSString *currentContent;
@property (retain, nonatomic) NSString *currentElement;
@property (retain, nonatomic) ASIS3Bucket *currentBucket;
@property (retain, nonatomic) NSString *ownerID;
@property (retain, nonatomic) NSString *ownerName;
@end

@implementation ASIS3ServiceRequest

Expand All @@ -16,5 +26,67 @@ + (id)serviceRequest
return [[[self alloc] initWithURL:[NSURL URLWithString:@"http://s3.amazonaws.com"]] autorelease];
}

- (void)dealloc
{
[buckets release];
[currentContent release];
[currentElement release];
[currentBucket release];
[ownerID release];
[ownerName release];
[super dealloc];
}

- (NSArray *)allBuckets
{
if ([self buckets]) {
return [self buckets];
}
[self setBuckets:[[[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 [self buckets];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
[self setCurrentElement:elementName];

if ([elementName isEqualToString:@"Bucket"]) {
[self setCurrentBucket:[ASIS3Bucket bucketWithOwnerID:[self ownerID] ownerName:[self ownerName]]];
}
[self setCurrentContent:@""];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"Bucket"]) {
[[self buckets] addObject:[self currentBucket]];
[self setCurrentBucket:nil];
} else if ([elementName isEqualToString:@"Name"]) {
[[self currentBucket] setName:[self currentContent]];
} else if ([elementName isEqualToString:@"CreationDate"]) {
[[self currentBucket] setCreationDate:[[ASIS3Request dateFormatter] dateFromString:[self currentContent]]];
} else if ([elementName isEqualToString:@"ID"]) {
[self setOwnerID:[self currentContent]];
} else if ([elementName isEqualToString:@"DisplayName"]) {
[self setOwnerName:[self currentContent]];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[self setCurrentContent:[[self currentContent] stringByAppendingString:string]];
}

@synthesize buckets;
@synthesize currentContent;
@synthesize currentElement;
@synthesize currentBucket;
@synthesize ownerID;
@synthesize ownerName;
@end
2 changes: 1 addition & 1 deletion Classes/S3/ASIS3BucketObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// Copyright 2009 All-Seeing Interactive. All rights reserved.
//
// Instances of this class represent objects stored in a bucket on S3
// ASIS3BucketRequests return an array of ASIS3BucketObject when you perform a list query
// ASIS3BucketRequests return an array of ASIS3BucketObjects when you perform a list query

#import <Foundation/Foundation.h>
@class ASIS3ObjectRequest;
Expand Down
31 changes: 20 additions & 11 deletions Classes/S3/ASIS3Request.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,40 @@ typedef enum _ASIS3ErrorType {

// Internally used while parsing errors
NSString *currentErrorString;

}

#pragma mark Constructors


// Uses the supplied date to create a Date header string
- (void)setDate:(NSDate *)date;

// Will return a dictionary of the 'amz-' headers that wil be sent to S3
// Override in subclasses to add new ones
- (NSMutableDictionary *)S3Headers;

// Returns the string that will used to create a signature for this request
// Is overridden in ASIS3ObjectRequest
- (NSString *)stringToSignForHeaders:(NSString *)canonicalizedAmzHeaders resource:(NSString *)canonicalizedResource;


# pragma mark encoding S3 key

+ (NSString *)stringByURLEncodingForS3Path:(NSString *)key;

#pragma mark Shared access keys
// Parses the response to work out if S3 returned an error
- (void)parseResponseXML;

#pragma mark shared access keys

// Get and set the global access key, this will be used for all requests the access key hasn't been set for
+ (NSString *)sharedAccessKey;
+ (void)setSharedAccessKey:(NSString *)newAccessKey;
+ (NSString *)sharedSecretAccessKey;
+ (void)setSharedSecretAccessKey:(NSString *)newAccessKey;
- (void)parseResponseXML;

# pragma mark helpers

// Returns a date formatter than can be used to parse a date from S3
+ (NSDateFormatter *)dateFormatter;

// URL-encodes an S3 key so it can be used in a url
// You shouldn't normally need to use this yourself
+ (NSString *)stringByURLEncodingForS3Path:(NSString *)key;



@property (retain) NSString *dateString;
@property (retain) NSString *accessKey;
Expand Down
Loading

0 comments on commit f3b6bc4

Please sign in to comment.