Start work on major S3 refactor, adding support for bucket and service requests
Showing
13 changed files
with
407 additions
and
181 deletions
@@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
21 | #import "ASIInputStream.h" | 21 | #import "ASIInputStream.h" |
22 | 22 | ||
23 | // Automatically set on build | 23 | // Automatically set on build |
24 | -NSString *ASIHTTPRequestVersion = @"v1.6-4 2010-03-16"; | 24 | +NSString *ASIHTTPRequestVersion = @"v1.6-5 2010-03-16"; |
25 | 25 | ||
26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
27 | 27 |
1 | // | 1 | // |
2 | -// ASIS3ListRequest.h | 2 | +// ASIS3BucketRequest.h |
3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest | 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest |
4 | // | 4 | // |
5 | -// Created by Ben Copsey on 13/07/2009. | 5 | +// Created by Ben Copsey on 16/03/2010. |
6 | -// Copyright 2009 All-Seeing Interactive. All rights reserved. | 6 | +// Copyright 2010 All-Seeing Interactive. All rights reserved. |
7 | // | 7 | // |
8 | +// Use this class to create buckets, fetch a list of their contents, and delete buckets | ||
8 | 9 | ||
9 | #import <Foundation/Foundation.h> | 10 | #import <Foundation/Foundation.h> |
10 | #import "ASIS3Request.h" | 11 | #import "ASIS3Request.h" |
12 | + | ||
11 | @class ASIS3BucketObject; | 13 | @class ASIS3BucketObject; |
12 | 14 | ||
13 | -@interface ASIS3ListRequest : ASIS3Request <NSCopying> { | 15 | +@interface ASIS3BucketRequest : ASIS3Request { |
16 | + // Name of the bucket to talk to | ||
17 | + NSString *bucket; | ||
18 | + NSString *subResource; | ||
14 | 19 | ||
15 | - // Options for filtering list requests | 20 | + // Options for filtering GET requests |
16 | // See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html | 21 | // See http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTBucketGET.html |
17 | NSString *prefix; | 22 | NSString *prefix; |
18 | NSString *marker; | 23 | NSString *marker; |
19 | int maxResultCount; | 24 | int maxResultCount; |
20 | - NSString *delimiter; | 25 | + NSString *delimiter; |
21 | 26 | ||
22 | // Internally used while parsing the response | 27 | // Internally used while parsing the response |
23 | NSString *currentContent; | 28 | NSString *currentContent; |
@@ -25,9 +30,25 @@ | @@ -25,9 +30,25 @@ | ||
25 | ASIS3BucketObject *currentObject; | 30 | ASIS3BucketObject *currentObject; |
26 | NSMutableArray *objects; | 31 | NSMutableArray *objects; |
27 | } | 32 | } |
28 | -// Create a list request | ||
29 | -+ (id)listRequestWithBucket:(NSString *)bucket; | ||
30 | 33 | ||
34 | +// Fetch a bucket | ||
35 | ++ (id)requestWithBucket:(NSString *)bucket; | ||
36 | + | ||
37 | +// Create a bucket request, passing a parameter in the query string | ||
38 | +// You'll need to parse the response XML yourself | ||
39 | +// Examples: | ||
40 | +// Fetch ACL: | ||
41 | +// ASIS3BucketRequest *request = [ASIS3BucketRequest requestWithBucket:@"mybucket" parameter:@"acl"]; | ||
42 | +// Fetch Location: | ||
43 | +// ASIS3BucketRequest *request = [ASIS3BucketRequest requestWithBucket:@"mybucket" parameter:@"location"]; | ||
44 | +// See the S3 REST API docs for more information about the parameters you can pass | ||
45 | ++ (id)requestWithBucket:(NSString *)bucket subResource:(NSString *)subResource; | ||
46 | + | ||
47 | +// Use for creating new buckets | ||
48 | ++ (id)PUTRequestWithBucket:(NSString *)bucket; | ||
49 | + | ||
50 | +// Use for deleting buckets (CAREFULL!) | ||
51 | ++ (id)DELETERequestWithBucket:(NSString *)bucket; | ||
31 | 52 | ||
32 | // Returns an array of ASIS3BucketObjects created from the XML response | 53 | // Returns an array of ASIS3BucketObjects created from the XML response |
33 | - (NSArray *)bucketObjects; | 54 | - (NSArray *)bucketObjects; |
@@ -35,6 +56,13 @@ | @@ -35,6 +56,13 @@ | ||
35 | //Builds a query string out of the list parameters we supplied | 56 | //Builds a query string out of the list parameters we supplied |
36 | - (void)createQueryString; | 57 | - (void)createQueryString; |
37 | 58 | ||
59 | + | ||
60 | +// Returns a date formatter than can be used to parse a date from S3 | ||
61 | ++ (NSDateFormatter *)dateFormatter; | ||
62 | + | ||
63 | + | ||
64 | +@property (retain) NSString *bucket; | ||
65 | +@property (retain) NSString *subResource; | ||
38 | @property (retain) NSString *prefix; | 66 | @property (retain) NSString *prefix; |
39 | @property (retain) NSString *marker; | 67 | @property (retain) NSString *marker; |
40 | @property (assign) int maxResultCount; | 68 | @property (assign) int maxResultCount; |
1 | // | 1 | // |
2 | -// ASIS3ListRequest.m | 2 | +// ASIS3BucketRequest.m |
3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest | 3 | // Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest |
4 | // | 4 | // |
5 | -// Created by Ben Copsey on 13/07/2009. | 5 | +// Created by Ben Copsey on 16/03/2010. |
6 | -// Copyright 2009 All-Seeing Interactive. All rights reserved. | 6 | +// Copyright 2010 All-Seeing Interactive. All rights reserved. |
7 | // | 7 | // |
8 | -#import "ASIS3ListRequest.h" | ||
9 | -#import "ASIS3BucketObject.h" | ||
10 | 8 | ||
9 | +#import "ASIS3BucketRequest.h" | ||
10 | +#import "ASIS3BucketObject.h" | ||
11 | 11 | ||
12 | static NSDateFormatter *dateFormatter = nil; | 12 | static NSDateFormatter *dateFormatter = nil; |
13 | 13 | ||
14 | + | ||
14 | // Private stuff | 15 | // Private stuff |
15 | -@interface ASIS3ListRequest () | 16 | +@interface ASIS3BucketRequest () |
16 | - @property (retain, nonatomic) NSString *currentContent; | 17 | +@property (retain, nonatomic) NSString *currentContent; |
17 | - @property (retain, nonatomic) NSString *currentElement; | 18 | +@property (retain, nonatomic) NSString *currentElement; |
18 | - @property (retain, nonatomic) ASIS3BucketObject *currentObject; | 19 | +@property (retain, nonatomic) ASIS3BucketObject *currentObject; |
19 | - @property (retain, nonatomic) NSMutableArray *objects; | 20 | +@property (retain, nonatomic) NSMutableArray *objects; |
20 | @end | 21 | @end |
21 | 22 | ||
22 | -@implementation ASIS3ListRequest | 23 | +@implementation ASIS3BucketRequest |
24 | + | ||
25 | ++ (NSDateFormatter *)dateFormatter | ||
26 | +{ | ||
27 | + if (!dateFormatter) { | ||
28 | + dateFormatter = [[NSDateFormatter alloc] init]; | ||
29 | + [dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; | ||
30 | + [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; | ||
31 | + [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'.000Z'"]; | ||
32 | + } | ||
33 | + return dateFormatter; | ||
34 | +} | ||
35 | + | ||
23 | 36 | ||
24 | -+ (void)initialize | 37 | ++ (id)requestWithBucket:(NSString *)bucket |
25 | { | 38 | { |
26 | - dateFormatter = [[NSDateFormatter alloc] init]; | 39 | + ASIS3ObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com",bucket]]] autorelease]; |
27 | - [dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]]; | 40 | + [request setBucket:bucket]; |
28 | - [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]]; | 41 | + return request; |
29 | - [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'.000Z'"]; | ||
30 | } | 42 | } |
31 | 43 | ||
32 | -+ (id)listRequestWithBucket:(NSString *)bucket | 44 | ++ (id)requestWithBucket:(NSString *)bucket subResource:(NSString *)subResource |
33 | { | 45 | { |
34 | - ASIS3ListRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com",bucket]]] autorelease]; | 46 | + ASIS3ObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com/?%@",bucket,subResource]]] autorelease]; |
35 | [request setBucket:bucket]; | 47 | [request setBucket:bucket]; |
48 | + [request setSubResource:subResource]; | ||
49 | + return request; | ||
50 | +} | ||
51 | + | ||
52 | + | ||
53 | ++ (id)PUTRequestWithBucket:(NSString *)bucket | ||
54 | +{ | ||
55 | + ASIS3BucketRequest *request = [self requestWithBucket:bucket]; | ||
56 | + [request setRequestMethod:@"PUT"]; | ||
57 | + return request; | ||
58 | +} | ||
59 | + | ||
60 | + | ||
61 | ++ (id)DELETERequestWithBucket:(NSString *)bucket | ||
62 | +{ | ||
63 | + ASIS3BucketRequest *request = [self requestWithBucket:bucket]; | ||
64 | + [request setRequestMethod:@"DELETE"]; | ||
36 | return request; | 65 | return request; |
37 | } | 66 | } |
38 | 67 | ||
@@ -45,9 +74,22 @@ static NSDateFormatter *dateFormatter = nil; | @@ -45,9 +74,22 @@ static NSDateFormatter *dateFormatter = nil; | ||
45 | [prefix release]; | 74 | [prefix release]; |
46 | [marker release]; | 75 | [marker release]; |
47 | [delimiter release]; | 76 | [delimiter release]; |
77 | + [subResource release]; | ||
78 | + [bucket release]; | ||
48 | [super dealloc]; | 79 | [super dealloc]; |
49 | } | 80 | } |
50 | 81 | ||
82 | +- (NSString *)canonicalizedResource | ||
83 | +{ | ||
84 | + if ([self subResource]) { | ||
85 | + return [NSString stringWithFormat:@"/%@/?%@",[self bucket],[self subResource]]; | ||
86 | + } | ||
87 | + return [NSString stringWithFormat:@"/%@/",[self bucket]]; | ||
88 | +} | ||
89 | + | ||
90 | + | ||
91 | + | ||
92 | + | ||
51 | - (void)createQueryString | 93 | - (void)createQueryString |
52 | { | 94 | { |
53 | NSMutableArray *queryParts = [[[NSMutableArray alloc] init] autorelease]; | 95 | NSMutableArray *queryParts = [[[NSMutableArray alloc] init] autorelease]; |
@@ -128,7 +170,9 @@ static NSDateFormatter *dateFormatter = nil; | @@ -128,7 +170,9 @@ static NSDateFormatter *dateFormatter = nil; | ||
128 | 170 | ||
129 | - (id)copyWithZone:(NSZone *)zone | 171 | - (id)copyWithZone:(NSZone *)zone |
130 | { | 172 | { |
131 | - ASIS3ListRequest *newRequest = [super copyWithZone:zone]; | 173 | + ASIS3BucketRequest *newRequest = [super copyWithZone:zone]; |
174 | + [newRequest setBucket:[self bucket]]; | ||
175 | + [newRequest setSubResource:[self subResource]]; | ||
132 | [newRequest setPrefix:[self prefix]]; | 176 | [newRequest setPrefix:[self prefix]]; |
133 | [newRequest setMarker:[self marker]]; | 177 | [newRequest setMarker:[self marker]]; |
134 | [newRequest setMaxResultCount:[self maxResultCount]]; | 178 | [newRequest setMaxResultCount:[self maxResultCount]]; |
@@ -136,7 +180,8 @@ static NSDateFormatter *dateFormatter = nil; | @@ -136,7 +180,8 @@ static NSDateFormatter *dateFormatter = nil; | ||
136 | return newRequest; | 180 | return newRequest; |
137 | } | 181 | } |
138 | 182 | ||
139 | - | 183 | +@synthesize bucket; |
184 | +@synthesize subResource; | ||
140 | @synthesize currentContent; | 185 | @synthesize currentContent; |
141 | @synthesize currentElement; | 186 | @synthesize currentElement; |
142 | @synthesize currentObject; | 187 | @synthesize currentObject; |
Classes/ASIS3ObjectRequest.h
0 → 100644
1 | +// | ||
2 | +// ASIS3ObjectRequest.h | ||
3 | +// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest | ||
4 | +// | ||
5 | +// Created by Ben Copsey on 16/03/2010. | ||
6 | +// Copyright 2010 All-Seeing Interactive. All rights reserved. | ||
7 | +// | ||
8 | +// Use this class to fetch, upload, copy and delete objects on Amazon S3 | ||
9 | + | ||
10 | +#import <Foundation/Foundation.h> | ||
11 | +#import "ASIS3Request.h" | ||
12 | + | ||
13 | + | ||
14 | +@interface ASIS3ObjectRequest : ASIS3Request { | ||
15 | + | ||
16 | + // Name of the bucket to talk to | ||
17 | + NSString *bucket; | ||
18 | + | ||
19 | + // Key of the resource you want to access on S3 | ||
20 | + NSString *key; | ||
21 | + | ||
22 | + // The bucket + path of the object to be copied (used with COPYRequestFromBucket:path:toBucket:path:) | ||
23 | + NSString *sourceBucket; | ||
24 | + NSString *sourceKey; | ||
25 | + | ||
26 | + // The mime type of the content for PUT requests | ||
27 | + // Set this if having the correct mime type returned to you when you GET the data is important (eg it will be served by a web-server) | ||
28 | + // Will be set to 'application/octet-stream' otherwise in iPhone apps, or autodetected on Mac OS X | ||
29 | + NSString *mimeType; | ||
30 | +} | ||
31 | + | ||
32 | +// Create a request, building an appropriate url | ||
33 | ++ (id)requestWithBucket:(NSString *)bucket key:(NSString *)key; | ||
34 | + | ||
35 | +// Create a request for an object, passing a parameter in the query string | ||
36 | +// You'll need to parse the response XML yourself | ||
37 | +// Examples: | ||
38 | +// Fetch ACL: | ||
39 | +// ASIS3ObjectRequest *request = [ASIS3ObjectRequest requestWithBucket:@"mybucket" key:@"my-key" parameter:@"acl"]; | ||
40 | +// Get object torret: | ||
41 | +// ASIS3ObjectRequest *request = [ASIS3ObjectRequest requestWithBucket:@"mybucket" key:@"my-key" parameter:@"torrent"]; | ||
42 | +// See the S3 REST API docs for more information about the parameters you can pass | ||
43 | ++ (id)requestWithBucket:(NSString *)bucket key:(NSString *)key subResource:(NSString *)subResource; | ||
44 | + | ||
45 | + | ||
46 | +// Create a PUT request using the file at filePath as the body | ||
47 | ++ (id)PUTRequestForFile:(NSString *)filePath withBucket:(NSString *)bucket key:(NSString *)key; | ||
48 | + | ||
49 | +// Create a PUT request using the supplied NSData as the body (set the mime-type manually with setMimeType: if necessary) | ||
50 | ++ (id)PUTRequestForData:(NSData *)data withBucket:(NSString *)bucket key:(NSString *)key; | ||
51 | + | ||
52 | +// Create a DELETE request for the object at path | ||
53 | ++ (id)DELETERequestWithBucket:(NSString *)bucket key:(NSString *)key; | ||
54 | + | ||
55 | +// Create a PUT request to copy an object from one location to another | ||
56 | +// Clang will complain because it thinks this method should return an object with +1 retain :( | ||
57 | ++ (id)COPYRequestFromBucket:(NSString *)sourceBucket key:(NSString *)sourceKey toBucket:(NSString *)bucket key:(NSString *)key; | ||
58 | + | ||
59 | +// Creates a HEAD request for the object at path | ||
60 | ++ (id)HEADRequestWithBucket:(NSString *)bucket key:(NSString *)key; | ||
61 | + | ||
62 | +@property (retain) NSString *bucket; | ||
63 | +@property (retain) NSString *key; | ||
64 | +@property (retain) NSString *sourceBucket; | ||
65 | +@property (retain) NSString *sourceKey; | ||
66 | +@property (retain) NSString *mimeType; | ||
67 | + | ||
68 | +@end |
Classes/ASIS3ObjectRequest.m
0 → 100644
1 | +// | ||
2 | +// ASIS3ObjectRequest.m | ||
3 | +// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest | ||
4 | +// | ||
5 | +// Created by Ben Copsey on 16/03/2010. | ||
6 | +// Copyright 2010 All-Seeing Interactive. All rights reserved. | ||
7 | +// | ||
8 | + | ||
9 | +#import "ASIS3ObjectRequest.h" | ||
10 | + | ||
11 | + | ||
12 | +@implementation ASIS3ObjectRequest | ||
13 | + | ||
14 | +- (ASIHTTPRequest *)HEADRequest | ||
15 | +{ | ||
16 | + ASIS3ObjectRequest *headRequest = (ASIS3ObjectRequest *)[super HEADRequest]; | ||
17 | + [headRequest setKey:[self key]]; | ||
18 | + [headRequest setBucket:[self bucket]]; | ||
19 | + return headRequest; | ||
20 | +} | ||
21 | + | ||
22 | ++ (id)requestWithBucket:(NSString *)bucket key:(NSString *)key | ||
23 | +{ | ||
24 | + NSString *path = [ASIS3Request stringByURLEncodingForS3Path:key]; | ||
25 | + ASIS3ObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com%@",bucket,path]]] autorelease]; | ||
26 | + [request setBucket:bucket]; | ||
27 | + [request setKey:key]; | ||
28 | + return request; | ||
29 | +} | ||
30 | + | ||
31 | ++ (id)requestWithBucket:(NSString *)bucket key:(NSString *)key subResource:(NSString *)subResource | ||
32 | +{ | ||
33 | + NSString *path = [ASIS3Request stringByURLEncodingForS3Path:key]; | ||
34 | + ASIS3ObjectRequest *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com%@?",bucket,path,subResource]]] autorelease]; | ||
35 | + [request setBucket:bucket]; | ||
36 | + [request setKey:key]; | ||
37 | + return request; | ||
38 | +} | ||
39 | + | ||
40 | ++ (id)PUTRequestForData:(NSData *)data withBucket:(NSString *)bucket key:(NSString *)key | ||
41 | +{ | ||
42 | + ASIS3ObjectRequest *request = [self requestWithBucket:bucket key:key]; | ||
43 | + [request appendPostData:data]; | ||
44 | + [request setRequestMethod:@"PUT"]; | ||
45 | + return request; | ||
46 | +} | ||
47 | + | ||
48 | ++ (id)PUTRequestForFile:(NSString *)filePath withBucket:(NSString *)bucket key:(NSString *)key | ||
49 | +{ | ||
50 | + ASIS3ObjectRequest *request = [self requestWithBucket:bucket key:key]; | ||
51 | + [request setPostBodyFilePath:filePath]; | ||
52 | + [request setShouldStreamPostDataFromDisk:YES]; | ||
53 | + [request setRequestMethod:@"PUT"]; | ||
54 | + [request setMimeType:[ASIHTTPRequest mimeTypeForFileAtPath:filePath]]; | ||
55 | + return request; | ||
56 | +} | ||
57 | + | ||
58 | ++ (id)DELETERequestWithBucket:(NSString *)bucket key:(NSString *)key | ||
59 | +{ | ||
60 | + ASIS3ObjectRequest *request = [self requestWithBucket:bucket key:key]; | ||
61 | + [request setRequestMethod:@"DELETE"]; | ||
62 | + return request; | ||
63 | +} | ||
64 | + | ||
65 | ++ (id)COPYRequestFromBucket:(NSString *)sourceBucket key:(NSString *)sourceKey toBucket:(NSString *)bucket key:(NSString *)key | ||
66 | +{ | ||
67 | + ASIS3ObjectRequest *request = [self requestWithBucket:bucket key:key]; | ||
68 | + [request setRequestMethod:@"PUT"]; | ||
69 | + [request setSourceBucket:sourceBucket]; | ||
70 | + [request setSourceKey:sourceKey]; | ||
71 | + return request; | ||
72 | +} | ||
73 | + | ||
74 | ++ (id)HEADRequestWithBucket:(NSString *)bucket key:(NSString *)key | ||
75 | +{ | ||
76 | + ASIS3ObjectRequest *request = [self requestWithBucket:bucket key:key]; | ||
77 | + [request setRequestMethod:@"HEAD"]; | ||
78 | + return request; | ||
79 | +} | ||
80 | + | ||
81 | + | ||
82 | + | ||
83 | +- (id)copyWithZone:(NSZone *)zone | ||
84 | +{ | ||
85 | + ASIS3ObjectRequest *newRequest = [super copyWithZone:zone]; | ||
86 | + [newRequest setBucket:[self bucket]]; | ||
87 | + [newRequest setKey:[self key]]; | ||
88 | + [newRequest setMimeType:[self mimeType]]; | ||
89 | + [newRequest setSourceBucket:[self sourceBucket]]; | ||
90 | + [newRequest setSourceKey:[self sourceKey]]; | ||
91 | + [newRequest setAccessPolicy:[self accessPolicy]]; | ||
92 | + return newRequest; | ||
93 | +} | ||
94 | + | ||
95 | +- (void)dealloc | ||
96 | +{ | ||
97 | + [bucket release]; | ||
98 | + [key release]; | ||
99 | + [mimeType release]; | ||
100 | + [sourceKey release]; | ||
101 | + [sourceBucket release]; | ||
102 | + [accessPolicy release]; | ||
103 | + [super dealloc]; | ||
104 | +} | ||
105 | + | ||
106 | +- (void)requestFinished | ||
107 | +{ | ||
108 | + // COPY requests return a 200 whether they succeed or fail, so we need to look at the XML to see if we were successful. | ||
109 | + if ([self responseStatusCode] == 200 && [self sourceKey] && [self sourceBucket]) { | ||
110 | + [self parseResponseXML]; | ||
111 | + return; | ||
112 | + } | ||
113 | + [super requestFinished]; | ||
114 | +} | ||
115 | + | ||
116 | +- (NSString *)canonicalizedResource | ||
117 | +{ | ||
118 | + return [NSString stringWithFormat:@"/%@%@",[self bucket],[ASIS3Request stringByURLEncodingForS3Path:[self key]]]; | ||
119 | +} | ||
120 | + | ||
121 | +- (NSMutableDictionary *)S3Headers | ||
122 | +{ | ||
123 | + NSMutableDictionary *headers = [NSMutableDictionary dictionary]; | ||
124 | + if ([self accessPolicy]) { | ||
125 | + [headers setObject:[self accessPolicy] forKey:@"x-amz-acl"]; | ||
126 | + } | ||
127 | + if ([self sourceKey]) { | ||
128 | + NSString *path = [ASIS3Request stringByURLEncodingForS3Path:[self sourceKey]]; | ||
129 | + [headers setObject:[[self sourceBucket] stringByAppendingString:path] forKey:@"x-amz-copy-source"]; | ||
130 | + } | ||
131 | + return headers; | ||
132 | +} | ||
133 | + | ||
134 | +- (NSString *)stringToSignForHeaders:(NSString *)canonicalizedAmzHeaders resource:(NSString *)canonicalizedResource | ||
135 | +{ | ||
136 | + if ([[self requestMethod] isEqualToString:@"PUT"] && ![self sourceKey]) { | ||
137 | + [self addRequestHeader:@"Content-Type" value:[self mimeType]]; | ||
138 | + return [NSString stringWithFormat:@"PUT\n\n%@\n%@\n%@%@",[self mimeType],dateString,canonicalizedAmzHeaders,canonicalizedResource]; | ||
139 | + } | ||
140 | + return [super stringToSignForHeaders:canonicalizedAmzHeaders resource:canonicalizedResource]; | ||
141 | +} | ||
142 | + | ||
143 | + | ||
144 | +@synthesize bucket; | ||
145 | +@synthesize key; | ||
146 | +@synthesize sourceBucket; | ||
147 | +@synthesize sourceKey; | ||
148 | +@synthesize mimeType; | ||
149 | +@synthesize accessPolicy; | ||
150 | +@end |
Classes/ASIS3ServiceRequest.h
0 → 100644
1 | +// | ||
2 | +// ASIS3ServiceRequest.h | ||
3 | +// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest | ||
4 | +// | ||
5 | +// Created by Ben Copsey on 16/03/2010. | ||
6 | +// Copyright 2010 All-Seeing Interactive. All rights reserved. | ||
7 | +// | ||
8 | +// Create an ASIS3ServiceRequest to obtain a list of your buckets | ||
9 | + | ||
10 | +#import <Foundation/Foundation.h> | ||
11 | +#import "ASIS3Request.h" | ||
12 | + | ||
13 | +@interface ASIS3ServiceRequest : ASIS3Request { | ||
14 | + | ||
15 | +} | ||
16 | + | ||
17 | ++ (id)serviceRequest; | ||
18 | + | ||
19 | +@end |
Classes/ASIS3ServiceRequest.m
0 → 100644
1 | +// | ||
2 | +// ASIS3ServiceRequest.m | ||
3 | +// Part of ASIHTTPRequest -> http://allseeing-i.com/ASIHTTPRequest | ||
4 | +// | ||
5 | +// Created by Ben Copsey on 16/03/2010. | ||
6 | +// Copyright 2010 All-Seeing Interactive. All rights reserved. | ||
7 | +// | ||
8 | + | ||
9 | +#import "ASIS3ServiceRequest.h" | ||
10 | + | ||
11 | + | ||
12 | +@implementation ASIS3ServiceRequest | ||
13 | + | ||
14 | ++ (id)serviceRequest | ||
15 | +{ | ||
16 | + return [[[self alloc] initWithURL:[NSURL URLWithString:@"http://s3.amazonaws.com"]] autorelease]; | ||
17 | +} | ||
18 | + | ||
19 | + | ||
20 | +@end |
@@ -5,9 +5,11 @@ | @@ -5,9 +5,11 @@ | ||
5 | // Created by Ben Copsey on 13/07/2009. | 5 | // Created by Ben Copsey on 13/07/2009. |
6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. | 6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. |
7 | // | 7 | // |
8 | +// Instances of this class represent objects stored in a bucket on S3 | ||
9 | +// ASIS3BucketRequests return an array of ASIS3BucketObject when you perform a list query | ||
8 | 10 | ||
9 | #import <Foundation/Foundation.h> | 11 | #import <Foundation/Foundation.h> |
10 | -@class ASIS3Request; | 12 | +@class ASIS3ObjectRequest; |
11 | 13 | ||
12 | @interface ASIS3BucketObject : NSObject <NSCopying> { | 14 | @interface ASIS3BucketObject : NSObject <NSCopying> { |
13 | 15 | ||
@@ -34,13 +36,13 @@ | @@ -34,13 +36,13 @@ | ||
34 | + (id)objectWithBucket:(NSString *)bucket; | 36 | + (id)objectWithBucket:(NSString *)bucket; |
35 | 37 | ||
36 | // Returns a request that will fetch this object when run | 38 | // Returns a request that will fetch this object when run |
37 | -- (ASIS3Request *)GETRequest; | 39 | +- (ASIS3ObjectRequest *)GETRequest; |
38 | 40 | ||
39 | // Returns a request that will replace this object with the contents of the file at filePath when run | 41 | // Returns a request that will replace this object with the contents of the file at filePath when run |
40 | -- (ASIS3Request *)PUTRequestWithFile:(NSString *)filePath; | 42 | +- (ASIS3ObjectRequest *)PUTRequestWithFile:(NSString *)filePath; |
41 | 43 | ||
42 | // Returns a request that will delete this object when run | 44 | // Returns a request that will delete this object when run |
43 | -- (ASIS3Request *)DELETERequest; | 45 | +- (ASIS3ObjectRequest *)DELETERequest; |
44 | 46 | ||
45 | @property (retain) NSString *bucket; | 47 | @property (retain) NSString *bucket; |
46 | @property (retain) NSString *key; | 48 | @property (retain) NSString *key; |
@@ -7,7 +7,7 @@ | @@ -7,7 +7,7 @@ | ||
7 | // | 7 | // |
8 | 8 | ||
9 | #import "ASIS3BucketObject.h" | 9 | #import "ASIS3BucketObject.h" |
10 | -#import "ASIS3Request.h" | 10 | +#import "ASIS3ObjectRequest.h" |
11 | 11 | ||
12 | @implementation ASIS3BucketObject | 12 | @implementation ASIS3BucketObject |
13 | 13 | ||
@@ -28,19 +28,19 @@ | @@ -28,19 +28,19 @@ | ||
28 | [super dealloc]; | 28 | [super dealloc]; |
29 | } | 29 | } |
30 | 30 | ||
31 | -- (ASIS3Request *)GETRequest | 31 | +- (ASIS3ObjectRequest *)GETRequest |
32 | { | 32 | { |
33 | - return [ASIS3Request requestWithBucket:[self bucket] key:[self key]]; | 33 | + return [ASIS3ObjectRequest requestWithBucket:[self bucket] key:[self key]]; |
34 | } | 34 | } |
35 | 35 | ||
36 | -- (ASIS3Request *)PUTRequestWithFile:(NSString *)filePath | 36 | +- (ASIS3ObjectRequest *)PUTRequestWithFile:(NSString *)filePath |
37 | { | 37 | { |
38 | - return [ASIS3Request PUTRequestForFile:filePath withBucket:[self bucket] key:[self key]]; | 38 | + return [ASIS3ObjectRequest PUTRequestForFile:filePath withBucket:[self bucket] key:[self key]]; |
39 | } | 39 | } |
40 | 40 | ||
41 | -- (ASIS3Request *)DELETERequest | 41 | +- (ASIS3ObjectRequest *)DELETERequest |
42 | { | 42 | { |
43 | - ASIS3Request *request = [ASIS3Request requestWithBucket:[self bucket] key:[self key]]; | 43 | + ASIS3ObjectRequest *request = [ASIS3ObjectRequest requestWithBucket:[self bucket] key:[self key]]; |
44 | [request setRequestMethod:@"DELETE"]; | 44 | [request setRequestMethod:@"DELETE"]; |
45 | return request; | 45 | return request; |
46 | } | 46 | } |
@@ -5,7 +5,8 @@ | @@ -5,7 +5,8 @@ | ||
5 | // Created by Ben Copsey on 30/06/2009. | 5 | // Created by Ben Copsey on 30/06/2009. |
6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. | 6 | // Copyright 2009 All-Seeing Interactive. All rights reserved. |
7 | // | 7 | // |
8 | -// A (basic) class for accessing data stored on Amazon's Simple Storage Service (http://aws.amazon.com/s3/) using the REST API | 8 | +// A class for accessing data stored on Amazon's Simple Storage Service (http://aws.amazon.com/s3/) using the REST API |
9 | +// While you can use this class directly, the included subclasses make typical operations easier | ||
9 | 10 | ||
10 | #import <Foundation/Foundation.h> | 11 | #import <Foundation/Foundation.h> |
11 | #import "ASIHTTPRequest.h" | 12 | #import "ASIHTTPRequest.h" |
@@ -34,27 +35,12 @@ typedef enum _ASIS3ErrorType { | @@ -34,27 +35,12 @@ typedef enum _ASIS3ErrorType { | ||
34 | // Your S3 secret access key. Set it on the request, or set it globally using [ASIS3Request setSharedSecretAccessKey:] | 35 | // Your S3 secret access key. Set it on the request, or set it globally using [ASIS3Request setSharedSecretAccessKey:] |
35 | NSString *secretAccessKey; | 36 | NSString *secretAccessKey; |
36 | 37 | ||
37 | - // Name of the bucket to talk to | ||
38 | - NSString *bucket; | ||
39 | - | ||
40 | - // Key of the resource you want to access on S3. Leave empty for the bucket root | ||
41 | - NSString *key; | ||
42 | - | ||
43 | // The string that will be used in the HTTP date header. Generally you'll want to ignore this and let the class add the current date for you, but the accessor is used by the tests | 38 | // The string that will be used in the HTTP date header. Generally you'll want to ignore this and let the class add the current date for you, but the accessor is used by the tests |
44 | NSString *dateString; | 39 | NSString *dateString; |
45 | - | 40 | + |
46 | - // The mime type of the content for PUT requests | 41 | + // The access policy to use when PUTting a file (see the string constants at the top ASIS3Request.h for details on what the possible options are) |
47 | - // Set this if having the correct mime type returned to you when you GET the data is important (eg it will be served by a web-server) | ||
48 | - // Will be set to 'application/octet-stream' otherwise in iPhone apps, or autodetected on Mac OS X | ||
49 | - NSString *mimeType; | ||
50 | - | ||
51 | - // The access policy to use when PUTting a file (see the string constants at the top of this header) | ||
52 | NSString *accessPolicy; | 42 | NSString *accessPolicy; |
53 | - | 43 | + |
54 | - // The bucket + path of the object to be copied (used with COPYRequestFromBucket:path:toBucket:path:) | ||
55 | - NSString *sourceBucket; | ||
56 | - NSString *sourceKey; | ||
57 | - | ||
58 | // Internally used while parsing errors | 44 | // Internally used while parsing errors |
59 | NSString *currentErrorString; | 45 | NSString *currentErrorString; |
60 | 46 | ||
@@ -62,29 +48,16 @@ typedef enum _ASIS3ErrorType { | @@ -62,29 +48,16 @@ typedef enum _ASIS3ErrorType { | ||
62 | 48 | ||
63 | #pragma mark Constructors | 49 | #pragma mark Constructors |
64 | 50 | ||
65 | -// Create a request, building an appropriate url | ||
66 | -+ (id)requestWithBucket:(NSString *)bucket key:(NSString *)key; | ||
67 | - | ||
68 | -// Create a PUT request using the file at filePath as the body | ||
69 | -+ (id)PUTRequestForFile:(NSString *)filePath withBucket:(NSString *)bucket key:(NSString *)key; | ||
70 | - | ||
71 | -// Create a PUT request using the supplied NSData as the body (set the mime-type manually with setMimeType: if necessary) | ||
72 | -+ (id)PUTRequestForData:(NSData *)data withBucket:(NSString *)bucket key:(NSString *)key; | ||
73 | - | ||
74 | -// Create a DELETE request for the object at path | ||
75 | -+ (id)DELETERequestWithBucket:(NSString *)bucket key:(NSString *)key; | ||
76 | - | ||
77 | -// Create a PUT request to copy an object from one location to another | ||
78 | -// Clang will complain because it thinks this method should return an object with +1 retain :( | ||
79 | -+ (id)COPYRequestFromBucket:(NSString *)sourceBucket key:(NSString *)sourceKey toBucket:(NSString *)bucket key:(NSString *)key; | ||
80 | - | ||
81 | -// Creates a HEAD request for the object at path | ||
82 | -+ (id)HEADRequestWithBucket:(NSString *)bucket key:(NSString *)key; | ||
83 | - | ||
84 | 51 | ||
85 | // Uses the supplied date to create a Date header string | 52 | // Uses the supplied date to create a Date header string |
86 | - (void)setDate:(NSDate *)date; | 53 | - (void)setDate:(NSDate *)date; |
87 | 54 | ||
55 | +- (NSMutableDictionary *)S3Headers; | ||
56 | +- (NSString *)stringToSignForHeaders:(NSString *)canonicalizedAmzHeaders resource:(NSString *)canonicalizedResource; | ||
57 | + | ||
58 | + | ||
59 | +# pragma mark encoding S3 key | ||
60 | + | ||
88 | + (NSString *)stringByURLEncodingForS3Path:(NSString *)key; | 61 | + (NSString *)stringByURLEncodingForS3Path:(NSString *)key; |
89 | 62 | ||
90 | #pragma mark Shared access keys | 63 | #pragma mark Shared access keys |
@@ -94,15 +67,10 @@ typedef enum _ASIS3ErrorType { | @@ -94,15 +67,10 @@ typedef enum _ASIS3ErrorType { | ||
94 | + (void)setSharedAccessKey:(NSString *)newAccessKey; | 67 | + (void)setSharedAccessKey:(NSString *)newAccessKey; |
95 | + (NSString *)sharedSecretAccessKey; | 68 | + (NSString *)sharedSecretAccessKey; |
96 | + (void)setSharedSecretAccessKey:(NSString *)newAccessKey; | 69 | + (void)setSharedSecretAccessKey:(NSString *)newAccessKey; |
97 | - | 70 | +- (void)parseResponseXML; |
98 | - | 71 | + |
99 | -@property (retain) NSString *bucket; | ||
100 | -@property (retain) NSString *key; | ||
101 | @property (retain) NSString *dateString; | 72 | @property (retain) NSString *dateString; |
102 | -@property (retain) NSString *mimeType; | ||
103 | @property (retain) NSString *accessKey; | 73 | @property (retain) NSString *accessKey; |
104 | @property (retain) NSString *secretAccessKey; | 74 | @property (retain) NSString *secretAccessKey; |
105 | @property (retain) NSString *accessPolicy; | 75 | @property (retain) NSString *accessPolicy; |
106 | -@property (retain) NSString *sourceBucket; | ||
107 | -@property (retain) NSString *sourceKey; | ||
108 | @end | 76 | @end |
@@ -19,9 +19,7 @@ static NSString *sharedSecretAccessKey = nil; | @@ -19,9 +19,7 @@ static NSString *sharedSecretAccessKey = nil; | ||
19 | 19 | ||
20 | // Private stuff | 20 | // Private stuff |
21 | @interface ASIS3Request () | 21 | @interface ASIS3Request () |
22 | - - (void)parseError; | ||
23 | + (NSData *)HMACSHA1withKey:(NSString *)key forString:(NSString *)string; | 22 | + (NSData *)HMACSHA1withKey:(NSString *)key forString:(NSString *)string; |
24 | - | ||
25 | @property (retain, nonatomic) NSString *currentErrorString; | 23 | @property (retain, nonatomic) NSString *currentErrorString; |
26 | @end | 24 | @end |
27 | 25 | ||
@@ -41,66 +39,11 @@ static NSString *sharedSecretAccessKey = nil; | @@ -41,66 +39,11 @@ static NSString *sharedSecretAccessKey = nil; | ||
41 | return path; | 39 | return path; |
42 | } | 40 | } |
43 | 41 | ||
44 | -+ (id)requestWithBucket:(NSString *)bucket key:(NSString *)key | ||
45 | -{ | ||
46 | - NSString *path = [ASIS3Request stringByURLEncodingForS3Path:key]; | ||
47 | - ASIS3Request *request = [[[self alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com%@",bucket,path]]] autorelease]; | ||
48 | - [request setBucket:bucket]; | ||
49 | - [request setKey:key]; | ||
50 | - return request; | ||
51 | -} | ||
52 | - | ||
53 | -+ (id)PUTRequestForData:(NSData *)data withBucket:(NSString *)bucket key:(NSString *)key | ||
54 | -{ | ||
55 | - ASIS3Request *request = [self requestWithBucket:bucket key:key]; | ||
56 | - [request appendPostData:data]; | ||
57 | - [request setRequestMethod:@"PUT"]; | ||
58 | - return request; | ||
59 | -} | ||
60 | - | ||
61 | -+ (id)PUTRequestForFile:(NSString *)filePath withBucket:(NSString *)bucket key:(NSString *)key | ||
62 | -{ | ||
63 | - ASIS3Request *request = [self requestWithBucket:bucket key:key]; | ||
64 | - [request setPostBodyFilePath:filePath]; | ||
65 | - [request setShouldStreamPostDataFromDisk:YES]; | ||
66 | - [request setRequestMethod:@"PUT"]; | ||
67 | - [request setMimeType:[ASIHTTPRequest mimeTypeForFileAtPath:filePath]]; | ||
68 | - return request; | ||
69 | -} | ||
70 | - | ||
71 | -+ (id)DELETERequestWithBucket:(NSString *)bucket key:(NSString *)key | ||
72 | -{ | ||
73 | - ASIS3Request *request = [self requestWithBucket:bucket key:key]; | ||
74 | - [request setRequestMethod:@"DELETE"]; | ||
75 | - return request; | ||
76 | -} | ||
77 | - | ||
78 | -+ (id)COPYRequestFromBucket:(NSString *)sourceBucket key:(NSString *)sourceKey toBucket:(NSString *)bucket key:(NSString *)key | ||
79 | -{ | ||
80 | - ASIS3Request *request = [self requestWithBucket:bucket key:key]; | ||
81 | - [request setRequestMethod:@"PUT"]; | ||
82 | - [request setSourceBucket:sourceBucket]; | ||
83 | - [request setSourceKey:sourceKey]; | ||
84 | - return request; | ||
85 | -} | ||
86 | - | ||
87 | -+ (id)HEADRequestWithBucket:(NSString *)bucket key:(NSString *)key | ||
88 | -{ | ||
89 | - ASIS3Request *request = [self requestWithBucket:bucket key:key]; | ||
90 | - [request setRequestMethod:@"HEAD"]; | ||
91 | - return request; | ||
92 | -} | ||
93 | - | ||
94 | - (void)dealloc | 42 | - (void)dealloc |
95 | { | 43 | { |
96 | - [bucket release]; | ||
97 | - [key release]; | ||
98 | [dateString release]; | 44 | [dateString release]; |
99 | - [mimeType release]; | ||
100 | [accessKey release]; | 45 | [accessKey release]; |
101 | [secretAccessKey release]; | 46 | [secretAccessKey release]; |
102 | - [sourceKey release]; | ||
103 | - [sourceBucket release]; | ||
104 | [super dealloc]; | 47 | [super dealloc]; |
105 | } | 48 | } |
106 | 49 | ||
@@ -119,11 +62,23 @@ static NSString *sharedSecretAccessKey = nil; | @@ -119,11 +62,23 @@ static NSString *sharedSecretAccessKey = nil; | ||
119 | ASIS3Request *headRequest = (ASIS3Request *)[super HEADRequest]; | 62 | ASIS3Request *headRequest = (ASIS3Request *)[super HEADRequest]; |
120 | [headRequest setAccessKey:[self accessKey]]; | 63 | [headRequest setAccessKey:[self accessKey]]; |
121 | [headRequest setSecretAccessKey:[self secretAccessKey]]; | 64 | [headRequest setSecretAccessKey:[self secretAccessKey]]; |
122 | - [headRequest setKey:[self key]]; | ||
123 | - [headRequest setBucket:[self bucket]]; | ||
124 | return headRequest; | 65 | return headRequest; |
125 | } | 66 | } |
126 | 67 | ||
68 | +- (NSMutableDictionary *)S3Headers | ||
69 | +{ | ||
70 | + return [NSMutableDictionary dictionary]; | ||
71 | +} | ||
72 | + | ||
73 | +- (NSString *)canonicalizedResource | ||
74 | +{ | ||
75 | + return @"/"; | ||
76 | +} | ||
77 | + | ||
78 | +- (NSString *)stringToSignForHeaders:(NSString *)canonicalizedAmzHeaders resource:(NSString *)canonicalizedResource | ||
79 | +{ | ||
80 | + return [NSString stringWithFormat:@"%@\n\n\n%@\n%@%@",[self requestMethod],[self dateString],canonicalizedAmzHeaders,canonicalizedResource]; | ||
81 | +} | ||
127 | 82 | ||
128 | - (void)buildRequestHeaders | 83 | - (void)buildRequestHeaders |
129 | { | 84 | { |
@@ -143,32 +98,19 @@ static NSString *sharedSecretAccessKey = nil; | @@ -143,32 +98,19 @@ static NSString *sharedSecretAccessKey = nil; | ||
143 | [self addRequestHeader:@"Date" value:[self dateString]]; | 98 | [self addRequestHeader:@"Date" value:[self dateString]]; |
144 | 99 | ||
145 | // Ensure our formatted string doesn't use '(null)' for the empty path | 100 | // Ensure our formatted string doesn't use '(null)' for the empty path |
146 | - NSString *canonicalizedResource = [NSString stringWithFormat:@"/%@%@",[self bucket],[ASIS3Request stringByURLEncodingForS3Path:[self key]]]; | 101 | + NSString *canonicalizedResource = [self canonicalizedResource]; |
147 | 102 | ||
148 | // Add a header for the access policy if one was set, otherwise we won't add one (and S3 will default to private) | 103 | // Add a header for the access policy if one was set, otherwise we won't add one (and S3 will default to private) |
149 | - NSMutableDictionary *amzHeaders = [[[NSMutableDictionary alloc] init] autorelease]; | 104 | + NSMutableDictionary *amzHeaders = [self S3Headers]; |
150 | NSString *canonicalizedAmzHeaders = @""; | 105 | NSString *canonicalizedAmzHeaders = @""; |
151 | - if ([self accessPolicy]) { | ||
152 | - [amzHeaders setObject:[self accessPolicy] forKey:@"x-amz-acl"]; | ||
153 | - } | ||
154 | - if ([self sourceKey]) { | ||
155 | - NSString *path = [ASIS3Request stringByURLEncodingForS3Path:[self sourceKey]]; | ||
156 | - [amzHeaders setObject:[[self sourceBucket] stringByAppendingString:path] forKey:@"x-amz-copy-source"]; | ||
157 | - } | ||
158 | for (NSString *header in [amzHeaders keyEnumerator]) { | 106 | for (NSString *header in [amzHeaders keyEnumerator]) { |
159 | canonicalizedAmzHeaders = [NSString stringWithFormat:@"%@%@:%@\n",canonicalizedAmzHeaders,[header lowercaseString],[amzHeaders objectForKey:header]]; | 107 | canonicalizedAmzHeaders = [NSString stringWithFormat:@"%@%@:%@\n",canonicalizedAmzHeaders,[header lowercaseString],[amzHeaders objectForKey:header]]; |
160 | - [self addRequestHeader:key value:[amzHeaders objectForKey:key]]; | 108 | + [self addRequestHeader:header value:[amzHeaders objectForKey:header]]; |
161 | } | 109 | } |
162 | 110 | ||
163 | 111 | ||
164 | // Jump through hoops while eating hot food | 112 | // Jump through hoops while eating hot food |
165 | - NSString *stringToSign; | 113 | + NSString *stringToSign = [self stringToSignForHeaders:canonicalizedAmzHeaders resource:canonicalizedResource]; |
166 | - if ([[self requestMethod] isEqualToString:@"PUT"] && ![self sourceKey]) { | ||
167 | - [self addRequestHeader:@"Content-Type" value:[self mimeType]]; | ||
168 | - stringToSign = [NSString stringWithFormat:@"PUT\n\n%@\n%@\n%@%@",[self mimeType],dateString,canonicalizedAmzHeaders,canonicalizedResource]; | ||
169 | - } else { | ||
170 | - stringToSign = [NSString stringWithFormat:@"%@\n\n\n%@\n%@%@",[self requestMethod],dateString,canonicalizedAmzHeaders,canonicalizedResource]; | ||
171 | - } | ||
172 | NSString *signature = [ASIHTTPRequest base64forData:[ASIS3Request HMACSHA1withKey:[self secretAccessKey] forString:stringToSign]]; | 114 | NSString *signature = [ASIHTTPRequest base64forData:[ASIS3Request HMACSHA1withKey:[self secretAccessKey] forString:stringToSign]]; |
173 | NSString *authorizationString = [NSString stringWithFormat:@"AWS %@:%@",[self accessKey],signature]; | 115 | NSString *authorizationString = [NSString stringWithFormat:@"AWS %@:%@",[self accessKey],signature]; |
174 | [self addRequestHeader:@"Authorization" value:authorizationString]; | 116 | [self addRequestHeader:@"Authorization" value:authorizationString]; |
@@ -179,21 +121,16 @@ static NSString *sharedSecretAccessKey = nil; | @@ -179,21 +121,16 @@ static NSString *sharedSecretAccessKey = nil; | ||
179 | 121 | ||
180 | - (void)requestFinished | 122 | - (void)requestFinished |
181 | { | 123 | { |
182 | - // COPY requests return a 200 whether they succeed or fail, so we need to look at the XML to see if we were successful. | ||
183 | - if ([self responseStatusCode] == 200 && [self sourceKey] && [self sourceBucket]) { | ||
184 | - [self parseError]; | ||
185 | - return; | ||
186 | - } | ||
187 | if ([self responseStatusCode] < 207) { | 124 | if ([self responseStatusCode] < 207) { |
188 | [super requestFinished]; | 125 | [super requestFinished]; |
189 | return; | 126 | return; |
190 | } | 127 | } |
191 | - [self parseError]; | 128 | + [self parseResponseXML]; |
192 | } | 129 | } |
193 | 130 | ||
194 | #pragma mark Error XML parsing | 131 | #pragma mark Error XML parsing |
195 | 132 | ||
196 | -- (void)parseError | 133 | +- (void)parseResponseXML |
197 | { | 134 | { |
198 | NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease]; | 135 | NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:[self responseData]] autorelease]; |
199 | [parser setDelegate:self]; | 136 | [parser setDelegate:self]; |
@@ -231,12 +168,6 @@ static NSString *sharedSecretAccessKey = nil; | @@ -231,12 +168,6 @@ static NSString *sharedSecretAccessKey = nil; | ||
231 | ASIS3Request *newRequest = [super copyWithZone:zone]; | 168 | ASIS3Request *newRequest = [super copyWithZone:zone]; |
232 | [newRequest setAccessKey:[self accessKey]]; | 169 | [newRequest setAccessKey:[self accessKey]]; |
233 | [newRequest setSecretAccessKey:[self secretAccessKey]]; | 170 | [newRequest setSecretAccessKey:[self secretAccessKey]]; |
234 | - [newRequest setBucket:[self bucket]]; | ||
235 | - [newRequest setKey:[self key]]; | ||
236 | - [newRequest setMimeType:[self mimeType]]; | ||
237 | - [newRequest setAccessPolicy:[self accessPolicy]]; | ||
238 | - [newRequest setSourceBucket:[self sourceBucket]]; | ||
239 | - [newRequest setSourceKey:[self sourceKey]]; | ||
240 | return newRequest; | 171 | return newRequest; |
241 | } | 172 | } |
242 | 173 | ||
@@ -266,7 +197,6 @@ static NSString *sharedSecretAccessKey = nil; | @@ -266,7 +197,6 @@ static NSString *sharedSecretAccessKey = nil; | ||
266 | } | 197 | } |
267 | 198 | ||
268 | 199 | ||
269 | - | ||
270 | #pragma mark S3 Authentication helpers | 200 | #pragma mark S3 Authentication helpers |
271 | 201 | ||
272 | // From: http://stackoverflow.com/questions/476455/is-there-a-library-for-iphone-to-work-with-hmac-sha-1-encoding | 202 | // From: http://stackoverflow.com/questions/476455/is-there-a-library-for-iphone-to-work-with-hmac-sha-1-encoding |
@@ -286,14 +216,10 @@ static NSString *sharedSecretAccessKey = nil; | @@ -286,14 +216,10 @@ static NSString *sharedSecretAccessKey = nil; | ||
286 | return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; | 216 | return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; |
287 | } | 217 | } |
288 | 218 | ||
289 | -@synthesize bucket; | 219 | + |
290 | -@synthesize key; | ||
291 | @synthesize dateString; | 220 | @synthesize dateString; |
292 | -@synthesize mimeType; | ||
293 | @synthesize accessKey; | 221 | @synthesize accessKey; |
294 | @synthesize secretAccessKey; | 222 | @synthesize secretAccessKey; |
295 | -@synthesize accessPolicy; | ||
296 | @synthesize currentErrorString; | 223 | @synthesize currentErrorString; |
297 | -@synthesize sourceBucket; | 224 | +@synthesize accessPolicy; |
298 | -@synthesize sourceKey; | ||
299 | @end | 225 | @end |
This diff is collapsed. Click to expand it.
This diff was suppressed by a .gitattributes entry.
-
Please register or login to post a comment